这个代码颠覆了C ++类型系统吗? [英] Does this code subvert the C++ type system?

查看:140
本文介绍了这个代码颠覆了C ++类型系统吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在C ++中有一个 const 方法意味着一个对象是只读的通过该方法,但它可能会改变否则。

I understand that having a const method in C++ means that an object is read-only through that method, but that it may still change otherwise.

然而,这个代码显然通过 const 引用更改一个对象(即通过 const method)。

However, this code apparently changes an object through a const reference (i.e. through a const method).

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

Is this code legal in C++?

如果是这样, const 类型系统的性能?为什么/为什么不?

If so: Is it breaking the const-ness of the type system? Why/why not?

如果没有:为什么不?

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



更新:



我已经将lambda移动到构造函数的初始化列表,因为这样允许我随后说 const BreakConst bc; ,因为 bc 现在是const(而不仅仅是指针) - 似乎暗示( by Stroustrup ),在构建之后以任何方式修改 bc 都会导致未定义的行为,即使构造函数和调用者没有办法知道这一点

Update:

I have migrated the lambda to the constructor's initialization list, since doing so allows me to subsequently say const BreakConst bc;, which -- because bc itself is now const (instead of merely the pointer) -- would seem to imply (by Stroustrup) that modifying bc in any way after construction should result in undefined behavior, even though the constructor and the caller would have no way of knowing this without seeing each others' definitions.

推荐答案

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

The oops() method isn't allowed to change the constness of the object. Furthermore it doesn't do it. Its your anonymous function that does it. This anonymous function isn't in the context of the object, but in the context of the main() method which is allowed to modify the object.

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

Your anonymous function doesn't change the this pointer of oops() (which is defined as const and therefore can't be changed) and also in no way derives some non-const variable from this this-pointer. Itself doesn't have any this-pointer. It just ignores the this-pointer and changes the bc variable of the main context (which is kind of passed as parameter to your closure). This variable is not const and therefore can be changed. You could also pass any anonymous function changing a completely unrelated object. This function doesn't know, that its changing the object that stores it.

如果你声明为

const BreakConst bc = ...

函数也会将它作为const对象处理,不能改变它。

then the main function also would handle it as const object and couldn't change it.

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

这篇关于这个代码颠覆了C ++类型系统吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆