C++ 类指针和所有权

史密斯1114

因此,我在 C++ 中重新创建了 Pong(使用 ncurses 进行终端 hijinks,因为尝试仅使用控制台进行操作被证明比我想象的要困难得多)。这有点意思是“刷新 C++”,因为它已经有一段时间了,我想使用 Unity 进行一些业余爱好游戏开发。

我想“好吧,我至少应该先用 C++ 制作一个简单的游戏,以证明我什至可以开始使用 Unity。Pong 是一个显而易见的选择,因为您需要处理:对象、游戏状态、碰撞、运动向量-ish。

在刷新 C++ 时,我不得不查找很多新的东西,并提醒自己忘记的东西(我接触 C++ 已经 10 年了)。我不太清楚的一件事是关于类的指针的亲密细节。(顺便说一句,这里有一个非常基本的带球和桨/碰撞的版本:https : //pastebin.com/5NHjEjxX到目前为止我只花了几个小时)。

具体来说,我不太记得的一件事显示在这里:

const int boardWidth = 60;
const int boardHeight = 12;
Ball ball = Ball(-1,1,(boardWidth/2),(boardHeight/2));
Ball *p_ball = &ball;
Paddle paddle1 = {4,(boardHeight/2),3};
Paddle *p_paddle1 = &paddle1;
Paddle paddle2 = {(boardWidth-4), (boardHeight/2),3};
Paddle *p_paddle2 = &paddle2;
Board board; 

(这是在游戏类初始化中。虽然我有点想知道我是否应该把它放在构造函数中)。尽管如此......特别是当我声明Ball ball = Ball(-1,1,(boardWidth/2),(boardHeight/2));Paddle paddle1 = {4,(boardHeight/2),3};这些项目在内存中“坐”在哪里?我假设堆?另外我将如何以正确的方式删除这些(例如球出界,我需要创建一个新球?)

我知道有一些关于所有权的事情……我觉得这是使用 & 的错误方式,因为例如 p_ball 实际上不会“拥有”那个类,而只是能够引用它,对吗?(我认为有一个术语“智能指针”,但上次我接触 C++ 时还没有真正出现过)。如果有更合适的方法,我很想知道!

我还被告知,无论如何在这些函数中通过引用传递可能更好,以避免使用指针并避免一起创建指针。

迈尔斯·布德内克

所有这些都是自动变量。当您到达当前范围的末尾时,它们的生命周期将结束。没有必要删除它们;一旦到达当前范围的末尾,这将自动发生。


如果您希望您的Game类对象拥有球、桨和板,那么它们具有成员范围是有意义的。IE

class Game {
public:
    static const int BOARD_WIDTH = 60;
    static const int BOARD_HEIGHT = 12;

    Game()
        : ball{-1, 1, BOARD_WIDTH / 2, BOARD_HEIGHT / 2},
          paddle1{4, BOARD_HEIGHT / 2, 3},
          paddle2{BOARD_WIDTH - 4, BOARD_HEIGHT / 2, 3}
    {}

private:
    Ball ball;
    Paddle paddle1;
    Paddle paddle2;
    Board board;
};

这些成员对象将共享对象的生命周期Game


指针只是指向其他对象的对象。它们不会影响它们指向的对象的生命周期。例如,您可以从方法返回指向对象成员的指针。请注意您的指针不会比它们指向的对象寿命更长。

如果你想让你的Game类包含指向其他对象的指针,那么你需要自己管理这些其他对象的生命周期。例如,您可以动态分配它们。与将对象直接包含在对象中相比,这几乎没有什么优势Game,并且会增加大量的复杂性和开销。

这里我std::unique_ptr用来做内存管理:

class Game {
public:
    static const int BOARD_WIDTH = 60;
    static const int BOARD_HEIGHT = 12;

    Game()
        : ball{std::make_unique<Ball>(-1, 1, BOARD_WIDTH / 2, BOARD_HEIGHT / 2)},
          paddle1{std::make_unique<Paddle>(4, BOARD_HEIGHT / 2, 3)},
          paddle2{std::make_unique<Paddle>(BOARD_WIDTH - 4, BOARD_HEIGHT / 2, 3)},
          board{std::make_unique<Board>()}
    {}

    // Copying is implicitly disallowed since std::unique_ptr is non-copyable.
    // You could implement a copy constructor and copy assignment operator to
    // do a deep copy

private:
    std::unique_ptr<Ball> ball;
    std::unique_ptr<Paddle> paddle1;
    std::unique_ptr<Paddle> paddle2;
    std::unique_ptr<Board> board;
};

或者,如果您真的愿意,您可以手动进行内存管理,但这样做几乎没有好处:

class Game {
public:
    static const int BOARD_WIDTH = 60;
    static const int BOARD_HEIGHT = 12;

    Game()
        : ball{new Ball(-1, 1, BOARD_WIDTH / 2, BOARD_HEIGHT / 2)},
          paddle1{new Paddle(4, BOARD_HEIGHT / 2, 3)},
          paddle2{new Paddle(BOARD_WIDTH - 4, BOARD_HEIGHT / 2, 3)},
          board{new Board()}
    {}

    // You must implement these yourself to do a deep copy when doing manual
    // memory management.  I've opted to delete them to disallow copying a Game object
    Game(const Game&) = delete;
    Game& operator=(const Game&) = delete;

    ~Game() {
        // every instance of 'new' must have exactly one matching 'delete'
        delete board;
        delete paddle2;
        delete paddle1;
        delete ball;
    }

private:
    Ball* ball;
    Paddle* paddle1;
    Paddle* paddle2;
    Board* board;
};

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章