代码之家  ›  专栏  ›  技术社区  ›  Dmitriano

为const类成员赋值

c++
  •  4
  • Dmitriano  · 技术社区  · 4 月前

    下面的代码中有UB吗?

    #include <iostream>
    
    int* p_n;
    
    class A
    {
    public:
    
        A(int val) : n(val)
        {
            // At this point the compiler does not know if the object is const or not.
            p_n = &n;
        }
    
        int n;
    };
    
    int main()
    {
        // A::n is const, because A is const, right?
        const A a(1);
    
        // but we change a const value here
        *p_n = 2;
    
        std::cout << a.n << std::endl;
    
        return 0;
    }
    

    分配之间有区别吗 *p_n 这样做?

    const_cast<A&>(a).n = 2;
    

    编辑

    here :

    const和volatile语义(7.1.6.1)不适用于正在构造的对象。当最派生对象(1.8)的构造函数结束时,它们生效。

    虽然对象 a 正在建设中,不是 const a.n 不是 const ,但他们成为 const 当构造函数结束时。

    确实如此 p_n 指向 const 对象与否?

    1 回复  |  直到 4 月前
        1
  •  6
  •   Remy Lebeau    4 月前

    对。代码试图修改 int 这是 const 它通过规避常量正确性来实现这一点,就像你已经发现的那样。

    // A::n is const, because A is const, right?
    const A a(1);
    

    对。 a const ,因此 a.n 无法修改。

    // but we change a const value here
    *p_n = 2;
    

    一旦你设法绕过 const 修改`a.n,这是不可修改的,所有赌注都已取消。代码具有未定义的行为。

    分配*p_n和这样做有区别吗:

    const_cast<A&>(a).n = 2;
    

    不。 const_cast 这并不能改变以下事实 const .

    考虑一下,你可以有一个指向const的指针,或者一个指向实际上不是const的对象的const引用,例如:

     int x = 42;
     const int& ref = x;
    

    在这里,您可以摆脱引用的约束来修改整数。整数不是 const .使用const引用不会改变对象本身不是 const 。与您的示例类似,任何指针技巧或强制转换都不会改变 .


    关于您的编辑。。。这并没有改变这样一个事实 const 而且 a.n 一旦建成 const 。您添加的引用仅解释了代码用于调用未定义行为的const正确性漏洞。

    原因是 const 仅在构造后应用,否则构造 const 这个物体将毫无用处。需要构造函数来建立类不变量,这通常需要修改对象。