C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 从“this”中抛弃constness然后更改成员值会调用未定义的行为吗?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
回复我对某些 answer in another question评论时,有人建议像
void C::f() const
{
  const_cast<C *>( this )->m_x = 1;
}

因为修改了const对象,所以会调用未定义的行为.这是真的?如果不是,请引用C标准(请提及您引用的标准),以获得此标准.

对于它的价值,我总是使用这种方法来避免使一个成员变量可变,如果只需要一两个方法写入它(因为使用mutable使其可写入所有方法).

解决方法

(尝试)修改const对象(C 11中的7.1.6.1/4)是未定义的行为.

所以重要的问题是,什么是const对象,并且m_x是一个?如果是,那么你有UB.如果不是,则此处没有任何内容表明它将是UB – 当然,由于此处未指出的其他原因(例如,数据竞争),它可能是UB.

如果在类C的const实例上调用函数f,则m_x是一个const对象,因此行为未定义(7.1.6.1/5):

const C c;
c.f(); // UB

如果在类C的非const实例上调用函数f,则m_x不是const对象,因此我们知道行为是定义的:

C c;
const C *ptr = &c;
c->f(); // OK

所以,如果你编写这个函数,那么你的用户不能创建一个C的const实例并在其上调用函数.也许C的实例只能由某个工厂创建,在这种情况下,您可以防止这种情况发生.

如果您希望数据成员可修改,即使完整对象是const,那么您应该将其标记为可变.这就是mutable的用途,即使在C的const实例上调用f,它也会为您提供定义的行为.

从C11开始,const成员函数和对可变数据成员的操作应该是线程安全的.否则,当您的类型与标准库函数和容器一起使用时,您违反了标准库提供的保证.

所以在C 11中你需要使m_x成为原子类型,或者以其他方式同步修改,或者作为最后的文档,即使它被标记为const,函数f也不是线程安全的.如果你没有做任何这些事情,那么你再次创造了一个机会让用户编写他们合理认为应该工作但实际上有UB的代码.

大佬总结

以上是大佬教程为你收集整理的c – 从“this”中抛弃constness然后更改成员值会调用未定义的行为吗?全部内容,希望文章能够帮你解决c – 从“this”中抛弃constness然后更改成员值会调用未定义的行为吗?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: