为什么RVO不会发生在赋值运算符中?(C++)

rmp*_*251 1 c++ assignment-operator rvo

例:

A myfunction() { return A(); }
A a = myfunction(); // default ctor only (return value optimization)
a = myfunction(); // default ctor and operator=
Run Code Online (Sandbox Code Playgroud)

为什么编译器不能将新对象写入现有对象?我相信一个类的所有实例占用相同数量的(非动态)内存,所以我不明白为什么这会是一个问题.

Mik*_*our 5

RVO 的工作原理是在调用者的堆栈帧上构造返回值。

在第一种情况下,可以直接在存储中构造它a,因为那里还没有对象。

在第二种情况下,那里已经有一个对象,因此在分配给 之前必须在其他地方构造它a。您不能在 之上构造新对象a,因为这不是赋值的工作方式。

  • @6502:确实,第一种情况不是赋值,这就是为什么我没有说它是。 (3认同)

Seb*_*edl 5

RVO的发生只是因为C++标准为编译器提供了一个特殊许可,可以忽略复制构造函数和临时构造函数中的副作用,这在应用优化后不会发生.

在赋值运算符中没有忽略副作用的特殊许可,因此不能省略.此外,由于a在分配之前它是有效的,因此首先必须对其进行破坏,以便可以在适当的位置构建新对象.不仅没有特殊的许可证来忽略这个析构函数调用引入的副作用,更糟糕的是,在函数调用之前必须发生破坏,然后如果函数抛出你会在哪里?