在此函数中使用引用参数有什么好处吗?

发布于 2024-08-06 16:01:21 字数 422 浏览 5 评论 0原文

我定义了以下类:

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

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

I have defined the following class:

class Action
{
    public: 
    Action(){ _bAllDone = false; }

    void AddMove( Move & m );
    private:
        std::deque<Move> _todo;
        bool _bAllDone;
};

The member AddMove is defined as follows:

void Action::AddMove( Move & m )
{ 
    _todo.push_back( m ); 
}

I noted that without the reference argument to this function the Copy Constructor was called twice, whereeas with a reference argument it was called only once. Is calling a Copy Constructor only once instead of twice a good reason to use a reference argument?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

戈亓 2024-08-13 16:01:21

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

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

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

The deque class in STL is supposed to maintain a copy of the element you pass to its push_back method. That is where one copy constructor comes from.

If you get rid of the reference in addMove(), you will first get a copy of the parameter (and thus one invocation of the copy constructor), and then when you push back, you will get a second copy.

The dual invocation of the copy constructor is wasteful so the reference is preferable. However, you should declare the parameter of addMove() as a const reference, to indicate to the caller that the element will not be modified. Under such an assurance (assuming you don't break it), it is safe to pass the object by reference without worrying and without paying the penalty of an object copy.

笑着哭最痛 2024-08-13 16:01:21

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

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

Seems like a big advantage to me. Things could get very slow if you are performing many adds iteratively. The actual amount of work would depend on the definition of Move and its copy constructor. And small changes could have severe effects on performance. Bite either way, passing by copy would still be twice as much work.

The overall effect of this will depend on how much of the entire processing is spend on this operation. Do it once, you'll never notice; do it a few thousand times, and it may be significant. However as a general principle, avoid copying data where you can safely reference it, especially since in this case there is no particular clarity or complexity issue - it is as easy to make it fast as it is to make it slow, so why would you make it slow?

坐在坟头思考人生 2024-08-13 16:01:21

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

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

华泰

It must be a reference, otherwise you'll be incurring an unnecessary (and potentially incorrect) copy of the argument. It should also be const, otherwise you'll unnecessarily restrict your callers.

Note also that names with a leading underscore are reserved to the language implementation, so your program is actualy "undefined".

HTH

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文