3

我知道修改声明为常量的对象是一个 UB。标题中提到的更复杂的例子呢?

class Foo
{
    public:
        Foo ( void ) { }
        int data;
};

int main ( void )
{
    const Foo foo;
    const_cast<Foo&>(foo).data = 0;   //  UB?
    return 0;
}

data被声明为非常量,所以可以修改它。但是foo被声明为const。所以看来我们不能修改它。因此我相信这里调用了一个 UB。我对吗?

更新:所以它实际上是一个UB。这意味着所有具有修改可变成员的假常量成员的类都会在常量实例上产生一个 UB。

class Foo
{
    public:
        mutable int data;
        Foo ( void ) { }
        void foo ( void ) const
        {
            some_modifications_of_data();
        }
};


const Foo foo;
foo.foo(); // UB?

这是否意味着如果你设计这种类,你必须明确提到在任何情况下都不能在常量实例上调用这个方法?

4

1 回答 1

5

用于const_cast修改数据const结构中的数据确实是未定义的行为。例外是标记的项目mutable。这些值的全部意义在于它们是可修改的,即使对象的其余部分是const. 它的真正意思是“但这个不是const”。

由于几乎所有内容const都是关于编译器检测修改的,尽管从技术上讲,编译器允许将一些const变量放在“不可写内存”中。关键字允许“mutable绕过”常量,因此如果对象具有可变组件,编译器不会将其const放入不可写的内存中,当然,它不会“反对”const正在修改的对象在它的可变组件中 - 即使在const函数内部。

于 2013-07-24T10:24:35.830 回答