use*_*635 13 c++ constructor const
C++11§12.1/ 14:
在构造const对象期间,如果通过未从构造函数的this指针直接或间接获得的左值访问对象或其任何子对象的值,则无法指定由此获得的对象或子对象的值.[例:
struct C;
void no_opt(C*);
struct C {
int c;
C() : c(0) { no_opt(this); }
};
const C cobj;
void no_opt(C* cptr) {
// value of cobj.c is unspecified
int i = cobj.c * 100;
cptr->c = 1;
// value of cobj.c is unspecified
cout << cobj.c * 100 << '\n';
}
Run Code Online (Sandbox Code Playgroud)
编译上面的示例输出100.我的问题是,为什么cobj.c在初始化列表0在进入构造函数之前将其设置为未指定的值?如果使用非const对象,这种行为有何不同?
const编译器可以将真正的对象视为合法常量.它可以假设它们的值永远不会改变甚至存储在const内存中,例如ROM或Flash.因此,this只要对象实际上不是常量,就需要使用由提供的非const访问路径.此条件仅在对象构造和销毁期间存在.
另外,我认为不需要对析构函数进行相应的要求,因为对象生存期已经结束,并且cobj.c一旦析构函数cobj开始就无法访问.
正如Matthieu所提到的那样,除了通过this施工或破坏之外,它还是一种强烈的"代码气味" .回顾C++11§3.8[basic.life]1和6,看起来cobj.c构造函数内部是UB的原因与它在析构函数中的相同,无论对象是什么const或§12.1/ 14,因为它的生命周期在初始化完成之前不会开始(构造函数返回).
它可能会起作用,但它会为优秀的C++程序员敲响警报,而且这本书是非法的.