【问题标题】:C++ Passing a Copy of an Object vs. Passing a Pointer to an Object?C++ 传递对象的副本与传递指向对象的指针?
【发布时间】:2010-10-26 16:46:12
【问题描述】:

这是我的 Game 类的构造函数:

// Construct a Game to be played with player on a copy of the board b.
Game(const Board& b, Player* player)
{
  ...
}

这是我使用构造函数的方式:

Player p("Player Name");
Board b(6,3);
Game g(b, &p);

这是如何工作的? b被复制了吗?

如果我想保存一个指向播放器的指针,我应该像下面这样创建一个私有 ivar 吗?

private:
  Player* _player;

...
// In Game constructor
_player = player;

【问题讨论】:

  • 附带说明:不要在 C++ 中为变量添加前缀“”,因为“”前缀是为 C 和 C++ 中的编译器供应商保留的。跨度>
  • 那我应该用什么名字呢?
  • 我确实想评论一下这可能很危险(这就是为什么 vector 实际上会复制对象而不是在调用 push_back 时获取引用)-例如gist.github.com/nadams810/6756139。该代码在 VC++/gcc 上工作得很好……但这只是偶然的运气,因为 CC 调用了析构函数,所以 x 应该不再可用。我并不是说你应该或不应该使用它——只是要注意你所传递的范围。

标签: c++ pointers class constructor


【解决方案1】:

如果您通过引用或指针传递,则不会复制。如果你想保存一个指针,那么是的,你需要一个地方来保存它。

请注意,使用构造函数初始化列表而不是赋值通常是更好的做法。喜欢:

Game( const Board& b, Player * player ) : _player( player )
{
    // do something with Board
}

到:

Game( const Board& b, Player * player )
{
    _player = player;
    // do something with Board
}

对于指针,没有太大区别,但对于更复杂的对象,使用初始化避免了赋值可能出现的语义和性能问题。

【讨论】:

  • 当分配给常量成员时,初始化列表是唯一的方式。
【解决方案2】:

如前所述,参数不会被复制,因为它是通过引用传递的。
但我想指出一些风格问题。

不要混搭你的风格。没有玩家可以玩游戏吗?如果不是,则通过引用传递播放器。

另一种组合。一个参数作为整个单词传递,另一个作为一个字母传递。

Game(const Board& board, Player& player):
    _player(player)    
{
  ...
}

private:
  Player& _player;

您可能还想存储 Board,因为它是有意义的。游戏可以“了解”棋盘。

private:
    const Board& _board;

那么你的构造函数将是

Game(const Board& board, Player& player):
    _board(board),
    _player(player)
{
  ...
}

【讨论】:

  • +1 指出不需要指针来避免复制——也可以使用引用。
【解决方案3】:

您正在通过reference 传递董事会,所以不,它没有被复制。

如果你以后有一些代码,比如:

Board _privateBoard = b;

那么你就是在复制b。但它不会被复制到函数中。

至于你的问题,是的,如果你想取回指针,你需要将指针存储在某个地方。

【讨论】:

  • "如果 _privateBoard 是 "Board" 而不是 "Board&",那么你是在复制 b,不是吗?
猜你喜欢
  • 1970-01-01
  • 2018-09-03
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 2014-03-31
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
相关资源
最近更新 更多