这段代码是否颠覆了C++类型系统?

Meh*_*dad 20 c++ const const-correctness pointer-aliasing

我知道const在C++ 中使用一个方法意味着一个对象通过该方法是只读的,但它可能仍然会改变.

但是,此代码显然通过const引用(即通过const方法)更改对象.

这段代码在C++中是否合法?

如果是这样:它是否打破const了类型系统的性质?为什么/为什么不呢?

如果没有:为什么不呢?

注1:我对这个例子进行了一些编辑,所以答案可能是指旧的例子.

编辑2:显然你甚至不需要C++ 11,所以我删除了那个依赖.

#include <iostream>

using namespace std;

struct DoBadThings { int *p; void oops() const { ++*p; } };

struct BreakConst
{
    int n;
    DoBadThings bad;
    BreakConst() { n = 0; bad.p = &n; } 
    void oops() const { bad.oops(); }  // can't change itself... or can it?
};

int main()
{
    const BreakConst bc;
    cout << bc.n << endl;   // 0
    bc.oops();              // O:)
    cout << bc.n << endl;   // 1

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

更新:

我已经将lambda迁移到构造函数的初始化列表,因为这样做允许我随后说const BreakConst bc;,因为bc 它本身现在是const(而不仅仅是指针) - 似乎暗示(通过Stroustrup)bc以任何方式修改在构造之后应该导致未定义的行为,即使构造函数和调用者在没有看到彼此的定义的情况下也无法知道这一点.

Hei*_*nzi 12

不允许oops()方法更改对象的常量.此外,它没有这样做.它是你的匿名功能.此匿名函数不在对象的上下文中,而是在允许修改对象的main()方法的上下文中.

你的匿名函数不会改变oops()的this指针(它被定义为const,因此无法更改),也绝不会从这个this-pointer派生出一些非const变量.它自己没有任何这个指针.它只是忽略this-pointer并更改主上下文的bc变量(它作为参数传递给闭包).此变量不是const,因此可以更改.您还可以传递任何匿名函数来更改完全不相关的对象.这个函数不知道,它改变了存储它的对象.

如果你要声明它

const BreakConst bc = ...
Run Code Online (Sandbox Code Playgroud)

然后main函数也将它作为const对象处理,并且无法更改它.

编辑: 换句话说:const属性绑定到访问对象的具体l值(引用).它不受对象本身的约束.