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

时间:2020-07-06 11:57:09

标签: c++ oop operator-overloading return-type

我试图查阅这本书,发现我的原因是重载<<操作符的操作符函数的原型是:

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;

此功能还具有参考参数。但是我们按值传递对象作为实际参数(在重载<<运算符中,我们必须按引用返回,因为我们必须将其传递给不能按值对象返回的引用参数,所以为什么我们在这里不这样做通过引用返回)。

1 个答案:

答案 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的结果上调用。