C ++ 17复制省略和对象销毁

时间:2018-12-13 13:29:23

标签: c++ c++17 copy-elision object-destruction

cppreference

  

发生复制省略时,实现将处理源和   省略的复制/移动(自C ++ 11起)操作的目标,就像两个   引用同一对象的不同方式,以及对对象的破坏   该对象发生在两个对象的时间较晚时   如果不进行优化,本来可以销毁的(除非,如果   所选构造函数的参数是对的右值引用   对象类型,销毁发生在目标本来可以   (自C ++ 17起)。

对于像A a = returnA();这样的简单情况,我可以理解,该对象并未在returnA()中被破坏,而是像稍后的A a;那样发生了破坏。 / p>

我不认为发生相反情况的情况是,复制/移动操作的源首先被破坏了。另外我想举一个自C ++ 17以来添加语句的示例(所选构造函数的参数是对对象类型的右值引用时的例外)

1 个答案:

答案 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变为可移动状态,则上面的(不明智的)代码将无效。