c++ - const对象的构造

标签 c++ constructor constants

C++11 §12.1/14:

During the construction of a const object, if the value of the object or any of its subobjects is accessed through an lvalue that is not obtained, directly or indirectly, from the constructor’s this pointer, the value of the object or subobject thus obtained is unspecified. [Example:

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';
}

编译上面的例子输出100。我的问题是为什么在进入构造函数之前初始化列表将其设置为 0 时应该未指定 cobj.c 的值?如果使用非常量对象,这种行为有何不同?

最佳答案

真正的 const 对象可以被编译器视为合法的常量。它可以假设它们的值永远不会改变甚至将它们存储在 const 内存中,例如ROM 或闪存。因此,您需要使用 this 提供的非常量访问路径,只要对象实际上不是常量即可。这种情况只存在于对象的构造和销毁过程中。

顺便说一句,我认为不需要对析构函数有相应的要求,因为对象的生命周期已经结束,并且 cobj.c 是不可访问的,因为 cobj开始。

正如 Matthieu 所提到的,在构造或销毁期间通过 this 访问对象是一种强烈的“代码气味”。回顾 C++11 §3.8 [basic.life] ¶1 和 6,构造函数内部的 cobj.c 似乎是 UB,原因与它在析构函数内部的原因相同,无论对象如何是 const 或 §12.1/14,因为它的生命周期直到初始化完成(构造函数返回)才开始。

它可能会起作用,但它会给优秀的 C++ 程序员敲响警钟,而且从书上看它是非法的。

关于c++ - const对象的构造,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8738929/

相关文章:

c++ - 当程序可见或最小化时进程 ID 发生变化

java - 常量数据成员

c++ - 从 C++ 角度来看 Python 中的重载构造函数

c++ - 什么时候不需要包含?

java - 如何使用 Guice 注入(inject)器创建对象?

java - 默认构造函数与内联字段初始化

c++ - 模板类 : No default constructor

PHP | define() 与 const

c++ - 将 const_cast 应用于字符串文字?

c++ - 赋值中使用的逗号运算符