副作用/易失性/复制构造函数/析构函数

时间:2010-08-31 02:55:20

标签: c++ constructor copy destructor volatile

参考讨论here

$ 3.7.1 / 2 - “如果静态存储持续时间的对象具有初始化或具有副作用的析构函数,即使它似乎未被使用也不应被删除,除非可以消除类对象或其副本如12.8中所述。“

$ 12.8 / 15-“当满足某些条件时,允许实现省略类对象的复制结构,即使该对象的复制构造函数和/或析构函数有副作用。”

在上述情况下,是一个案例的具体示例,即使是易失性读/写也可能被优化掉(例如,如果复制构造函数对volatile变量有读/写)。

所以问题是“即使复制构造函数具有对volatile变量的读/写,也可以省略复制构造函数吗?”

2 个答案:

答案 0 :(得分:0)

仅当命名对象是非易失性时才允许NRVO [它在您引用的同一部分中的权利,即第一个子弹],否则我不明白为什么不这样做。毕竟,如果你创建的对象是易变的,你仍然在写它,你只是不是通过复制构造函数这样做。并且它没有限定允许忽略哪些副作用,所以很明显,如果易失性读/写在复制构造函数本身内,编译器就不必关心。

答案 1 :(得分:0)

有时。有趣的是你应该问,因为我误解了volatile(约翰尼斯叫出来的)让我查出了这样的琐事。

§12.8/ 15:

  

在函数的return语句中   用类返回类型的时候   表达式是一个名称   用非易失性自动对象   同样的cv-unqualified类型   函数返回类型,副本   操作可以省略   构造自动对象   直接进入函数的返回   值

因此,可以通过删除构造函数来消除volatile访问,但是如果整个对象是易变的则不行。

此外,如果函数按值而不是普通volatile foo返回foo ,那么可以有所作为,因为构造了volatile暂时不能被省略!

foo factory_a(); // return class by value
const foo factory_b(); // also return by value: rather pointless
volatile foo factory_c(); // implies no elision

请注意,返回的临时的cv限定也会影响临时的访问语义,例如factory_b().non_const_method()是非法的。所以这比愚蠢的更加神秘。