【问题标题】:Is there any advantage in using a reference argument in this function?在这个函数中使用引用参数有什么好处吗?
【发布时间】:2010-12-04 01:48:47
【问题描述】:

我已经定义了以下类:

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

我注意到,如果没有此函数的引用参数,复制构造函数会被调用两次,而如果有引用参数,它只会被调用一次。只调用一次复制构造函数而不是两次是使用引用参数的好理由吗?

【问题讨论】:

    标签: c++ reference copy-constructor


    【解决方案1】:

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

    还请注意,带有前导下划线的名称保留给语言实现,因此您的程序实际上是“未定义的”。

    HTH

    【讨论】:

      【解决方案2】:

      STL 中的 deque 类应该维护您传递给其 push_back 方法的元素的副本。这就是一个复制构造函数的来源。

      如果你去掉 addMove() 中的引用,你将首先得到一个参数的副本(因此会调用一次复制构造函数),然后当你推回时,你会得到第二个副本。

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

      【讨论】:

      • 一个很好的答案,+1 将其作为 const 传递。
      • 另一个重要原因(我想说更重要的原因,IMO,如果您的代码已经设计为不修改引用)通过引用传递给 const 是允许临时变量被接受为参数(例如,如果AddMove 采用const Move&amp;,则action.AddMove(Move(/* ... */)); 有效,但如果仅采用Move&amp; 则无效)
      【解决方案3】:

      对我来说似乎是一个很大的优势。如果您迭代地执行许多添加,事情可能会变得非常缓慢。实际工作量取决于 Move 的定义及其复制构造函数。微小的变化可能会对性能产生严重影响。无论哪种方式,通过副本传递仍然是两倍的工作量。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-02
        • 2022-12-17
        • 2014-08-27
        • 2018-05-30
        • 2019-10-12
        • 2010-10-14
        • 1970-01-01
        相关资源
        最近更新 更多