示例:
A myfunction() { return A(); }
A a = myfunction(); // default ctor only (return value optimization)
a = myfunction(); // default ctor and operator=
为什么编译器不能将新对象写入现有对象?我相信一个类的所有实例占用相同数量的(非动态)内存,所以我不明白为什么这会是一个问题。
答案 0 :(得分:5)
RVO的发生只是因为C ++标准为编译器提供了一个特殊许可,可以忽略复制构造函数和临时构造函数中的副作用,这在应用优化后不会发生。
在赋值运算符中没有忽略副作用的特殊许可,因此不能省略。此外,由于a
在分配之前是有效的,因此首先必须对其进行破坏,以便可以在适当的位置构建新对象。这个析构函数调用不仅没有特别许可来忽略引入的副作用,更糟糕的是破坏必须在函数调用之前发生,然后如果函数抛出你会在哪里?
答案 1 :(得分:4)
RVO的工作原理是在调用者的堆栈帧上构造返回值。
在第一种情况下,它可以直接在a
的存储中构建,因为那里还没有对象。
在第二种情况下,那里已有一个对象,因此在分配给a
之前必须在其他地方构建它。您无法在a
之上构建新对象,因为这不是分配的工作方式。