You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何可将const *this传入非const成员方法?——重载加法运算符的C++编译疑问

关于C++中右值调用非const成员函数的疑问解答

首先来看你提供的代码:

#include <iostream>
using namespace std;
class Real {
public:
    int re;
    explicit Real(int num = 0) { re = num; }
    Real operator + (const Real& real) {
        return Real(re + real.re);
    }
};
int main() {
    Real real2(4), real3(3);
    Real real4 = (Real)6 + real2 + real3;
    cout << real4.re << endl;
    return 0;
}

你的疑问是:

该代码可正常编译且输出结果为13。但我认为编译器会先执行(Real)6 + real2操作,在此操作中*this是右值,因此它应为const类型,相当于将const *this传入了非const成员方法,原本以为这会导致编译失败,然而实际并未如此。请问我的逻辑误区出在哪里?感谢解答。

你的逻辑误区拆解

核心问题在于你把右值对象和const对象的概念混淆了,咱们一步步理清楚:

  • 首先,(Real)6创建的是一个非const的临时右值对象。C++里的右值只是表示这个对象是临时的、可以被移动或销毁,但它本身并没有被标记为const——除非你显式声明它是const Real(6)这种形式。
  • 非const成员函数(比如你的operator+)的限制是:只能被非const对象调用,不管这个对象是左值还是右值。你的临时右值是非const的,所以完全符合调用条件。
  • 那什么时候会触发编译错误?如果你的临时对象是const的(比如const Real(6)),这时候调用非const的operator+才会报错,因为const对象只能调用const限定的成员函数。

补充一点:虽然你的operator+没有修改*this的内容,但编译器不会因为这一点自动把它当成const成员函数——如果你想让这个运算符支持const对象调用,应该把它声明为Real operator + (const Real& real) const,这样不管是左值、右值、const对象都能调用它。

总结来说:右值≠const对象,只有显式声明为const的对象,才会被限制只能调用const成员函数。你的代码里的临时右值是非const的,所以调用非const的operator+完全合法。

内容的提问来源于stack exchange,提问作者sadcat_1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 13:38:12