发生复制省略时,实现将处理源和 省略的复制/移动(自C ++ 11起)操作的目标,就像两个 引用同一对象的不同方式,以及对对象的破坏 该对象发生在两个对象的时间较晚时 如果不进行优化,本来可以销毁的(除非,如果 所选构造函数的参数是对的右值引用 对象类型,销毁发生在目标本来可以 (自C ++ 17起)。
对于像A a = returnA();
这样的简单情况,我可以理解,该对象并未在returnA()
中被破坏,而是像稍后的A a;
那样发生了破坏。 / p>
我不认为发生相反情况的情况是,复制/移动操作的源首先被破坏了。另外我想举一个自C ++ 17以来添加语句的示例(所选构造函数的参数是对对象类型的右值引用时的例外)
答案 0 :(得分:3)
当prvalue是参数时,源超过目标的对称情况:
struct A {
static int *data;
A() {if(!refs++) data=new int(42);}
A(const A&) {++refs;} // not movable
~A() {if(!--refs) delete data;}
private:
static int refs;
};
int A::refs,*A::data;
int* f(A) {return A::data;}
A returnA();
int returnInt() {return *f(returnA());} // ok
由于returnA()
的结果是临时的,因此其生存期延长到return
语句的 full-expression 的末尾。该实现可以使用f
的参数来识别它,但是在f
返回时不能销毁它,因此returnInt
中的取消引用是有效的。 (请注意,参数may survive that long仍然如此。)
C ++ 17中的调整(并保证省略)是,如果您(将)移动,则prvalue可能会在参数为时被销毁(因为您不应无论如何都要依靠它的内容)。如果那是f
返回的时刻,那么如果A
变为可移动状态,则上面的(不明智的)代码将无效。