【发布时间】:2020-08-17 21:06:12
【问题描述】:
这是我一直在思考的问题,但从未找到任何资源来说明这个问题的答案。事实上,它不仅适用于+=,也适用于其兄弟姐妹,即-=、*=、/= 等(当然不是==)。
考虑这个例子,
int a = 5;
a += 4;
//this will make 'a' 9
现在考虑等价的表达式:
a = a + 4;
//This also makes 'a' 9
如果 += 只是 a = a + <rhs of +=> 的简写
重载 + 运算符也应该隐式重载+=,除非另有显式重载。但事实并非如此。这意味着,a += b 不会转换为 a = a + b。但是为什么不以这种方式实施呢?就像在编译期间将其简单地转换为a = a + b 而不是将其作为运算符单独实现不是更容易吗?这也有助于运算符重载,其中a += b、a 和b 是同一类的对象不必显式重载,只需重载+ 就足够了?
编辑:
this 答案让我的问题变得更加清晰
让我用一个需要重载运算符的例子来解释我的问题:
class A {
int ivar;
public:
A() = default;
A(int par_ivar) : ivar(par_ivar) { }
A(A& a) {
this.ivar = a.ivar;
}
A(A&& a) noexcept {
this.ivar = a.ivar;
}
A operator+(const A& a) const {
A temp_a;
temp_a.ivar = this.ivar + a.ivar;
return temp_a;
}
void operator=(const A& a) {
this.ivar = a.ivar;
}
~A() = default;
};
现在,让我们看看 2 个程序的结果:
prog1:
int main() {
A a1(2);
A a2(3);
a1 = a1 + a2; //a1.ivar = 5
return 0;
}
程序2:
int main() {
A a1(2);
A a2(3);
a1 += a2; //compilation error!!
return 0;
}
即使两个程序都打算做,不,做同样的事情,一个编译并运行(希望我的重载是正确的)另一个甚至没有编译!如果 += 被简单地替换为适当的 + 和 =,我们就不会觉得需要显式重载 +=。这是有意的,还是等待添加的功能?
【问题讨论】:
-
“现在考虑到 += 只是一个简写” - 不完全是。
a在a += b中只被评估一次,而a = a + b将让a被评估两次。如果a涉及函数调用,那将是一个主要区别。 -
运算符不是从其他人生成的(除了在 C++20 中使用/来自
<=>):提供operator <不允许a > b(这在“逻辑上”确实等同于@ 987654350@)。你必须实现所有(甚至通过重用一些)。 -
没有“背景”。对于类类型
+=和+是不同的运算符 -
当我为一个类重载自己的
+和+=运算符时,我按照+=实现+,而不是相反。