我试图查阅这本书,发现我的原因是重载<<操作符的操作符函数的原型是:
friend ostream& operator<<(ostream&, const className&);
现在考虑以下语句:
cout << myRectangle << yourRectangle;
此语句等效于该语句:
operator<<(operator<<(cout, myRectangle), yourRectangle); //Line A
因为运算符<<的关联性是从左到右。 要执行上一条语句,必须首先执行以下表达式:
cout << myRectangle
即表达式:
operator<<(cout, myRectangle)
执行此表达式后,将输出myRectangle的值,无论 函数运算符<<返回的值将成为 运算符<<(即运算符<<的第一个参数)以便输出 对象yourRectangle的值(请参见A行中的语句)。左侧 操作符<<的参数必须是ostream类型的对象,因此表达式: cout << myRectangle 必须将对象cout(而不是其值)返回到第二个运算符<< in的左侧 为了输出yourRectangle的值。 因此,函数operator <<的返回类型必须是对对象的引用 属于ostream类型。
这意味着您不能通过值将对象作为自变量传递,而形式参数则通过引用来接受它。因此,对我来说很有意义,为什么在重载<<运算符时为什么要通过引用返回。但是,让我感到困惑的是此语句:
tempRectangle = myRectangle + yourRectangle + anyRectangle;
根据运算符的优先级和关联性,编译器将首先执行:
myRectangle + yourRectangle
等同于:
myRectangle.operator+ (yourRectangle); // Line B
►这是我的第一个困惑,即在执行第B行之后,它将按值返回对象(然后将其与第三个对象(即anyRectangle)相加)。那么,如何用B行写这个加法呢(因为我们没有该对象的任何名称,该对象是按值返回的,所以它如何执行这个加法运算)。
►第二个困惑是在添加该语句中的所有三个对象之后:
tempRectangle = myRectangle + yourRectangle + anyRectangle;
我们有一个按值返回的对象,然后将该对象传递给operator =函数以为其分配tempRectangle。现在,与<<运算符一样。由于operator =函数的原型是:
className operator+(const className&) const;
此功能还具有参考参数。但是我们按值传递对象作为实际参数(在重载<<运算符中,我们必须按引用返回,因为我们必须将其传递给不能按值对象返回的引用参数,所以为什么我们在这里不这样做通过引用返回)。
答案 0 :(得分:0)
如评论operator=
中所述,应返回引用。另一方面,operator+
是不同的,因为
auto c = a + b;
operator+
通常会使两个操作数保持不变,并创建一个新对象作为结果。例如
struct foo {
int value;
foo operator+(const foo& other) const {
foo result;
result.value = value + other.value;
return result;
}
};
如果您像这样链接operator+
auto c = (a + b) + c;
然后operator+(c)
或a
都不会调用b
,而是在a+b
的结果上调用。