我定义了以下类:
class Action
{
public:
Action(){ _bAllDone = false; }
void AddMove( Move & m );
private:
std::deque<Move> _todo;
bool _bAllDone;
};
成员AddMove的定义如下:
void Action::AddMove( Move & m )
{
_todo.push_back( m );
}
我注意到,如果没有此函数的引用参数,则复制构造函数被调用两次,并且带有引用参数的wheree只调用一次。是仅仅调用一次复制构造函数而不是两次,这是使用引用参数的充分理由吗?
答案 0 :(得分:17)
STL中的deque类应该保留传递给push_back方法的元素的副本。这就是一个拷贝构造函数来自的地方。
如果你在addMove()中删除了引用,你将首先得到一个参数的副本(因此一次调用复制构造函数),然后当你向后推时,你将获得第二个副本。 / p>
复制构造函数的双重调用是浪费的,因此引用更可取。但是,您应该将addMove()的参数声明为const引用,以向调用者指示不会修改该元素。在这样的保证下(假设你不破坏它),可以安全地通过引用传递对象而不用担心并且不支付对象副本的惩罚。
答案 1 :(得分:4)
对我来说似乎是一个很大的优势。如果你迭代地执行许多添加,事情可能变得非常缓慢。实际工作量取决于Move及其复制构造函数的定义。小的变化可能会对性能产生严重影响。无论哪种方式,通过复制仍然是两倍的工作。
这样做的总体效果取决于整个处理在此操作上花费了多少。做一次,你永远不会注意到;做几千次,这可能很重要。但是作为一般原则,避免复制数据,你可以安全地引用它,特别是因为在这种情况下没有特别的清晰度或复杂性问题 - 它很容易使它快速,因为它使它变慢,所以为什么你会慢慢来?
答案 2 :(得分:0)
必须是一个参考,否则你将会产生一个不必要的(也可能是不正确的)参数副本。它也应该是const
,否则您将不必要地限制您的来电者。
另请注意,带有前导下划线的名称保留给语言实现,因此您的程序实际上是“未定义的”。
HTH