为什么在重载 = 运算符时通过引用 return?
Why return by reference while overloading = operator?
我知道这方面已经有很多问题了,所以请多多包涵。
所以我找到了this问题,对此我有一个修改的疑问
class Blah {
public:
Blah();
Blah(int x, int y);
int x;
int y;
Blah operator =(Blah rhs);
};
Blah::Blah() {}
Blah::Blah(int xp, int yp) {
x = xp;
y = yp;
}
Blah Blah::operator =(Blah rhs) {
x = rhs.x;
y = rhs.y;
return *this;
}
int main() {
Blah b1(2, 3);
Blah b2(4, 1);
Blah b3(8, 9);
Blah b4(7, 5);
b3 = b4 = b2 = b1;
cout << b3.x << ", " << b3.y << endl;
cout << b4.x << ", " << b4.y << endl;
cout << b2.x << ", " << b2.y << endl;
cout << b1.x << ", " << b1.y << endl;
return 0;
}
所以我没有在这里通过引用使用 return,同时重载 = 运算符,我仍然得到预期的输出。
为什么我要 return 引用?我看到的唯一区别是,在按值 returning 时调用了复制构造函数,但在按引用 returning 时没有调用复制构造函数。
有人可以为我简化一下并通过参考解释 returning 背后的 concept/idea 吗?我的 class 大约一年前就教过它,但我仍然不明白。
Why return by reference while overloading = operator?
因为:
- 复制有时代价高昂,在这种情况下最好避免。
- 这是约定俗成的。这也是基本类型的内置赋值运算符、classes 的编译器生成的赋值运算符以及所有标准类型的赋值运算符(据我所知)的工作方式。
鉴于您定义的特殊成员函数没有做任何特殊的事情,我建议改为遵循 class 定义:
struct Blah {
int x;
int y;
};
这里没有严格的对错之分。你可以用运算符重载做一些奇怪的事情,有时这是合适的。但是,很少有充分的理由 return 来自 operator=
的新实例。
return 值是启用链接。您的链接测试不完整。您的线路:
b3 = b4 = b2 = b1;
与
相同
b3 = (b4 = (b2 = b1));
你会看到这个案例的预期输出。但是,像这样链接
(b3 = b4) = b1;
应该先把b4
赋给b3
,然后把b1
赋给b3
。或者您可能想调用 returned 引用的方法:
(b3 = b4).foo();
当你 return 一个副本时,第二个赋值将是临时的,成员函数 foo
将在临时上调用,而不是像预期的那样在 b3
上调用。要查看实际效果,请考虑 this
的输出
int main() {
Blah b1(2, 3);
Blah b2(4, 1);
Blah b3(8, 9);
Blah b4(7, 5);
(b3 = b4) = b1;
cout << b3.x << ", " << b3.y << endl;
cout << b1.x << ", " << b1.y << endl;
return 0;
}
当 return复制时:
7, 5
2, 3
当 return引用时:
2, 3
2, 3
更简单的原因是你不想return在不需要复制的时候复制。
我知道这方面已经有很多问题了,所以请多多包涵。
所以我找到了this问题,对此我有一个修改的疑问
class Blah {
public:
Blah();
Blah(int x, int y);
int x;
int y;
Blah operator =(Blah rhs);
};
Blah::Blah() {}
Blah::Blah(int xp, int yp) {
x = xp;
y = yp;
}
Blah Blah::operator =(Blah rhs) {
x = rhs.x;
y = rhs.y;
return *this;
}
int main() {
Blah b1(2, 3);
Blah b2(4, 1);
Blah b3(8, 9);
Blah b4(7, 5);
b3 = b4 = b2 = b1;
cout << b3.x << ", " << b3.y << endl;
cout << b4.x << ", " << b4.y << endl;
cout << b2.x << ", " << b2.y << endl;
cout << b1.x << ", " << b1.y << endl;
return 0;
}
所以我没有在这里通过引用使用 return,同时重载 = 运算符,我仍然得到预期的输出。
为什么我要 return 引用?我看到的唯一区别是,在按值 returning 时调用了复制构造函数,但在按引用 returning 时没有调用复制构造函数。
有人可以为我简化一下并通过参考解释 returning 背后的 concept/idea 吗?我的 class 大约一年前就教过它,但我仍然不明白。
Why return by reference while overloading = operator?
因为:
- 复制有时代价高昂,在这种情况下最好避免。
- 这是约定俗成的。这也是基本类型的内置赋值运算符、classes 的编译器生成的赋值运算符以及所有标准类型的赋值运算符(据我所知)的工作方式。
鉴于您定义的特殊成员函数没有做任何特殊的事情,我建议改为遵循 class 定义:
struct Blah {
int x;
int y;
};
这里没有严格的对错之分。你可以用运算符重载做一些奇怪的事情,有时这是合适的。但是,很少有充分的理由 return 来自 operator=
的新实例。
return 值是启用链接。您的链接测试不完整。您的线路:
b3 = b4 = b2 = b1;
与
相同b3 = (b4 = (b2 = b1));
你会看到这个案例的预期输出。但是,像这样链接
(b3 = b4) = b1;
应该先把b4
赋给b3
,然后把b1
赋给b3
。或者您可能想调用 returned 引用的方法:
(b3 = b4).foo();
当你 return 一个副本时,第二个赋值将是临时的,成员函数 foo
将在临时上调用,而不是像预期的那样在 b3
上调用。要查看实际效果,请考虑 this
int main() {
Blah b1(2, 3);
Blah b2(4, 1);
Blah b3(8, 9);
Blah b4(7, 5);
(b3 = b4) = b1;
cout << b3.x << ", " << b3.y << endl;
cout << b1.x << ", " << b1.y << endl;
return 0;
}
当 return复制时:
7, 5
2, 3
当 return引用时:
2, 3
2, 3
更简单的原因是你不想return在不需要复制的时候复制。