谁在+运算符中删除了复制的实例?(C++)

Oop*_*ser 9 c++ memory copy variable-assignment operator-keyword

我搜索了如何在互联网上正确实现+运算符,我找到的所有结果都执行以下步骤:

const MyClass MyClass::operator+(const MyClass &other) const
{
    MyClass result = *this;  // Make a copy of myself. Same as MyClass result(*this);
    result += other;         // Use += to add other to the copy.
    return result;           // All done!
}
Run Code Online (Sandbox Code Playgroud)

关于这个"过程"我几乎没有问题:

  1. 以这种方式实现+运算符不是那么愚蠢,它在第一行调用赋值运算符(复制类),然后在返回中调用复制构造函数(由于返回的事实,它也复制了类)按价值,所以它破坏了第一个副本并创建了一个新的......坦白说,这并不是很聪明......)

  2. 当我写a = b + c时,b + c部分创建该类的新副本,然后'a ='部分将副本复制给自己.谁删除了b + c创建的副本?

  3. 有没有更好的方法来实现+运算符而不需要两次处理类,也没有任何内存问题?

提前致谢

Dav*_*ley 6

  1. 这实际上不是赋值运算符,而是复制构造函数.毕竟像添加这样的操作会创建一个新值,因此必须在某处创建它.这比看起来更有效,因为编译器可以自由地进行返回值优化,这意味着它可以直接在下一次使用它的地方构造值.

  2. result声明为一个局部变量,因此消失在函数调用中-除非静脉阻塞(见上文)被使用,在这种情况下,这是从来没有的功能其实创建,但在调用者.

  3. 并不是的; 这种方法比它最初看起来效率更高.


Jer*_*fin 5

在这种情况下,我可能会考虑这样的事情:

MyClass MyClass::operator+(MyClass other) { 
     other += *this;
     return other;
}
Run Code Online (Sandbox Code Playgroud)

戴夫·亚伯拉罕写了一篇文章而回,解释它是如何工作以及为什么这样的代码通常是即使它最初看来似乎不应该是很有效的一个.

编辑(谢谢MSalters):是的,这确实假设/取决于持有的可交换财产MyClass.如果a+b != b+a,则原始代码是您想要的(大多数相同的推理适用).

  • 请注意,这为字符串提供了令人惊讶的结果.`MyString("a")+ MyString("b")== MyString("ba")`!它仅在a + b == b + a时有效 (3认同)
  • 只需使用一个自由函数而不是一个成员(通过值传递第一个参数,然后通过const ref传递第二个参数),这会省略交换问题,改进类的封装并具有相同的用法. (3认同)