C++:传递对象的副本与传递对象指针之间的区别?

4

这是我的游戏类的构造函数:

// 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被复制了吗?
如果我想保存一个player的指针,我应该创建一个类似下面的私有变量吗?
private:
  Player* _player;

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

顺便提一下,在C++中不要以“_”为前缀命名变量,因为在C和C++中,“_”前缀是为编译器供应商保留的。 - Johann Gerell
1
那么我应该使用什么名称呢? - Elliot
我想评论一下,这可能是危险的(这就是为什么vector在调用push_back时实际上会复制对象而不是使用引用),例如 https://gist.github.com/nadams810/6756139。那段代码在VC++/gcc上运行得很好......但这只是幸运的,因为CC的析构函数被调用,所以x不应再被使用。我并不是说你应该或不应该使用它 - 只是要注意传递的范围。 - Natalie Adams
3个回答

8
如果你通过引用或指针传递参数,那么不会进行拷贝。如果你想要保存一个指针,那么是的,你需要一个地方来保存它。
请注意,通常最好使用构造函数初始化列表而不是赋值。建议:
Game( const Board& b, Player * player ) : _player( player )
{
    // do something with Board
}

to:

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

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


当给常量成员赋值时,初始化列表是唯一的方法。 - Dario

6

正如所述,参数不会被复制,因为它是按引用传递的。
但我想指出一些样式问题。

不要混合你的风格。如果没有玩家,能玩游戏吗?如果不能,请通过引用传递玩家。

另一个混合。您将一个参数作为整个单词传递,另一个参数作为一个字母传递。

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

private:
  Player& _player;

可能您还想将棋盘存储下来,因为这样更有意义。游戏可以“知道”棋盘。

private:
    const Board& _board;

那么你的构造函数将是:
Game(const Board& board, Player& player):
    _board(board),
    _player(player)
{
  ...
}

+1 是指出不需要使用指针来避免复制,也可以使用引用。 - anon

2

您正在通过引用传递该板,因此不会被复制。

如果您稍后有一些代码,例如:

Board _privateBoard = b;

然后你正在复制 b。但它没有被复制到函数中。

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


如果 _privateBoard 是 "Board" 而不是 "Board&",那么你就在复制 b 了,对吧? - David Schmitt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接