C++运算符重载疑问:三类表达式的operator+重载是否相同?
嘿,这个问题问得挺到位的——这三个操作完全不共用同一个operator+重载,每个背后的逻辑都有区别,我给你逐个掰扯清楚:
Option 1:
x = a + x
这里左操作数是A类对象a,右操作数是int类型的x。编译器会优先查找A类的成员运算符重载,也就是你提到的int A::operator+(int s)(建议加上const修饰,因为这个操作不应该修改a本身,写成int A::operator+(int s) const更规范)。如果A类里定义了这个成员函数,就能直接匹配上。Option 2:
x = x + a
这次左操作数是int的x,右操作数是A类对象a。这时候A类的成员operator+就派不上用场了——因为成员运算符的左操作数必须是当前类的对象。这时候有两种合法的匹配路径:- 你定义了一个全局的非成员运算符重载:
int operator+(int lhs, const A& rhs),编译器会直接调用这个; - 如果A类有一个可以把int隐式转换为A对象的转换构造函数(比如
A(int val);),编译器会把x转换成A对象,然后调用A类的成员operator+(相当于A(x) + a),但这属于隐式转换后的间接调用,不是直接使用你说的那个成员重载。
如果以上两种情况都没有,这段代码会直接编译报错。
- 你定义了一个全局的非成员运算符重载:
Option 3:
x += a
这个是复合赋值运算符operator+=,和operator+完全是两个独立的运算符!它不会调用任何operator+重载,而是需要单独实现operator+=的重载。因为x是int类型,所以需要的是全局重载:int& operator+=(int& lhs, const A& rhs)。当然,如果A类有operator int()这类可以把A对象隐式转换为int的函数,编译器也会自动转换后执行普通的int加法,但这也和你问的int A::operator+(int s)没有关系。
总结
只有Option 1会直接用到你提到的int A::operator+(int s)成员重载;Option 2要么用全局的operator+(int, const A&),要么依赖隐式转换间接调用成员重载;Option 3则完全使用operator+=的重载,和operator+无关。
内容的提问来源于stack exchange,提问作者Kumar Roshan Mehta




