构造const对象

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对象,这种行为有何不同?

Pot*_*ter 6

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++程序员敲响警报,而且这本书是非法的.