为何返回const C的赋值运算符可赋值给非const C对象?
CV限定符与赋值运算符的误区解析
你的核心误解在于混淆了赋值操作的执行过程和赋值表达式的返回值。
1. c = cc的实际行为
c = cc在C++中等价于调用c.operator=(cc):
c是一个非const对象,完全有权调用你定义的operator=成员函数(你的operator=没有const限定,属于非const成员函数,可被非const实例调用)。- 赋值的核心逻辑是在
operator=函数内部完成的:函数通过this指针直接修改了c对象本身,而不是返回一个新对象再赋值给c。
2. 返回值const C的作用
你把operator=的返回值设为const C,但这个返回值只是整个赋值表达式的结果,不会触发对c的二次赋值。它的存在主要是为了支持链式赋值(比如a = b = c),但在你的代码里,这个返回值没有被使用,所以不会产生任何“const对象赋值给非const变量”的问题。
3. 为什么没有调用复制构造函数
代码输出只有copy assignment,没有打印复制构造函数的信息,是因为C++的返回值优化(RVO):当你在operator=里返回C{}时,编译器会直接在返回值的目标位置构造这个临时对象,省略了额外的复制操作,所以不会触发复制构造函数。
再回头看你之前的认知
你提到“编译器通过创建副本移除CV限定”,但这个场景和你的测试代码无关——你的测试代码里根本没有需要移除CV限定的复制操作,赋值是直接修改原对象,而非创建副本后覆盖原对象。
内容的提问来源于stack exchange,提问作者Thomas W.
相关产品推荐
相关产品推荐

