2009-10-05 51 views
2

我定义了以下类:在此函数中使用引用参数是否有任何优势?

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); 
} 

我注意到没有这个函数的引用参数,复制构造函数被调用了两次,有一个引用参数只被调用一次。仅调用一次复制构造函数而不是两次是使用引用参数的充分理由吗?

回答

17

STL中的deque类应该保留传递给它的push_back方法的元素的副本。这是一个拷贝构造函数来自哪里。

如果您在addMove()中删除了引用,您将首先获取该参数的副本(并因此调用复制构造函数),然后当您推回时,您将获得第二个副本。

复制构造函数的双重调用是浪费的,所以引用是可取的。但是,您应该将addMove()的参数声明为一个const引用,以向调用方指示该元素不会被修改。在这样的保证下(假设你不打破它),通过引用传递对象是安全的,不用担心,也不需要支付对象副本的惩罚。

+0

一个很好的答案,+1将它作为const传递。 – 2009-10-05 20:18:59

+2

另一个重要的原因(我认为更重要的原因,IMO,如果你的代码已经设计为不修改引用)通过引用传递给const是允许临时接受参数(例如'action.AddMove( Move(/ * ... * /));'如果'AddMove'采用'const Move&',则是有效的,但如果仅需一个'Move&'则无效) – GRB 2009-10-05 20:51:14

4

对我来说这似乎是一个很大的优势。如果你迭代地执行多次添加,事情会变得非常缓慢。实际的工作量取决于Move及其拷贝构造函数的定义。而小的变化可能会对性能产生严重影响。咬一口,通过复制仍然是两倍的工作。

这样做的整体效果将取决于整个处理花费在此操作上的多少。做一次,你永远不会注意到;做几千次,这可能很重要。但作为一般原则,避免在可以安全地引用数据的位置复制数据,尤其是因为在这种情况下,没有特别的明确性或复杂性问题 - 使它变得尽可能快,因为它使它变得缓慢,那么为什么要让它变慢?

0

必须是一个参考,否则你会产生一个不必要的(并可能不正确)的参数副本。它也应该是const,否则你将不必要地限制你的呼叫者。

还要注意带有前导下划线的名字是保留给语言实现的,所以你的程序实际上是“未定义的”。

HTH

相关问题