为什么可以通过使用指向对象成员的指针的 const 成员函数来修改对象状态?

问题描述

为什么这段代码不会产生编译器错误

class C
{
    int _i{ 123 };
    int* ptr{ &_i };
public:
    int& i() const { return *ptr; }
};

int main()
{
    C const c;
    c.i() += 321;
    return c.i();
}

标准中有没有关于这种行为的字眼?当然,也许无论如何都没有必要指向可以直接访问的成员,但是在堆上拥有也可以视为对象的一部分的资源呢?

解决方法

在对象的构造和销毁过程中,成员不是const。这意味着您可以存储一个非常量指针,该指针指向一个成员,一旦对象被构造,该成员将成为 const。使用该指针来更改 const 对象的值是未定义的行为。引用 cppreference

通过非常量访问路径修改常量对象并通过非易失性泛左值引用易失性对象会导致未定义的行为。

并引用 [dcl.type.cv]/4

除了任何声明为 mutable 的类成员都可以修改之外,任何在其生命周期内修改 const 对象的尝试都会导致未定义的行为。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...