提问者:小点点

为什么我们在重载<<运算符时通过引用返回对象,而不在重载=和+运算符时通过引用返回对象? [副本]


我试着查阅了这本书,我在那里找到的原因是操作符函数的原型重载<<<; 操作员是:

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(而不是它的值)返回到第二个运算符<<; 以便输出YourRectangle的值。 因此,函数运算符的返回类型<<<; 必须是对ostream类型对象的引用。

这意味着,在形参通过引用获取对象的情况下,不能将对象作为实参按值传递。 因此,在重载<<<; 接线员。 但让我感到困惑的是这句话:

tempRectangle = myRectangle + yourRectangle + anyRectangle;

根据运算符的优先级和关联性,编译器将首先执行:

myRectangle + yourRectangle

相当于:

myRectangle.operator+ (yourRectangle); // Line B

我的第一个困惑是,在执行B行之后,它将按值返回对象(然后将由第三个对象(即anyRectangle)添加)。 那么,如何按照B行来写这个加法(因为我们没有由值返回的对象的任何名称,所以它是如何执行这个加法的)。

第二个困惑是,在这个语句中添加了所有三个对象之后:

tempRectangle = myRectangle + yourRectangle + anyRectangle;

我们有一个return-by-value对象,然后将该对象传递给operator=function,以便为其分配TemPrecTangle。 现在,这是相同的情况,它发生了<<<; 接线员。 由于operator=函数的原型是:

className operator+(const className&) const;

这个函数还有一个引用参数。 但是我们将对象按值传递为一个实际的参数(在重载<<>运算符中,我们使用了按引用返回,因为我们必须将它传递给不能按值返回对象的引用参数,所以为什么我们在这里不这样做,即按引用返回)。


共1个答案

匿名用户

正如注释中提到的,operator=应该返回一个引用。 另一方面,运算符+是不同的,因为在

auto c = a + b;

运算符+通常保持两个操作数不变,结果创建一个新对象。 例如

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;

运算符+(c)既不对a也不对b调用,而是对a+b的结果调用。