我知道修改声明为常量的对象是UB。如何在标题中提到更复杂的例子?
class Foo
{
public:
Foo ( void ) { }
int data;
};
int main ( void )
{
const Foo foo;
const_cast<Foo&>(foo).data = 0; // UB?
return 0;
}
data
被声明为非const,因此可以修改它。但是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?
这是否意味着如果您设计这种类,您必须明确提到在任何情况下都没有人可以在常量实例上调用此方法?
答案 0 :(得分:5)
使用const_cast
修改const
数据结构中的数据确实是未定义的行为。例外情况是标记为mutable
的项目。这些值的重点在于,即使对象的其余部分为const
,它们也是可修改的。它的确意味着“但这一个不是const
”。
由于几乎所有const
都与编译器检测到修改有关,但从技术上讲,编译器允许在“不可写内存”中放置一些const
变量。 mutable
关键字允许“绕过”constness,因此编译器不会将const
对象放入不可写的内存中(如果它有可变组件),当然,它即使在const
函数内,也不会“反对”const
对象被修改的可变组件。