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