C++中给const类成员赋值是否存在UB?两种修改方式有何区别?
问题解答
1. 代码是否存在未定义行为?
存在未定义行为。
原因:对象a是const A类型,构造完成后,它的所有成员都具备const语义,不可被修改。虽然在构造函数执行时,对象还未成为const,p_n获取了成员n的非const指针,但构造结束后,a及其成员n的const属性正式生效。此时通过*p_n = 2修改原本属于const对象的成员,属于修改const限定的对象,违反了C++标准中const对象不可修改的规则,触发未定义行为。
2. *p_n = 2与const_cast<A&>(a).n = 2的区别?
两种方式本质上都是试图绕过const限制修改const对象的成员,最终都会触发未定义行为,但形式上有差异:
*p_n = 2:借助构造阶段获取的非const指针间接修改,属于“隐式”绕过const——指针是在对象还不是const时获取的,但后续对象变为const后,该指针的使用就违反了const语义。const_cast<A&>(a).n = 2:通过const_cast显式移除对象的const属性,直接修改成员,是更直白的const绕过操作。
3. p_n是否指向const对象?
构造函数执行期间,对象a还未成为const,此时p_n = &n获取的是非const int的指针,指向的是一个普通成员变量。但当构造完成后,整个a成为const对象,其成员n也随之成为const int的一部分。此时p_n的类型虽然是int*,但它实际指向的内存区域属于const对象的成员,从语义上来说,此时它指向的是一个const限定的对象。
内容的提问来源于stack exchange,提问作者Dmitriano
相关产品推荐
相关产品推荐

