操作员超载疑惑

时间:2016-02-28 16:11:50

标签: c++ class operator-overloading operators

我试图编写一些运算符重载函数,尤其是<<运算符,将它与自定义类和std::ofstream对象一起使用,但我对各种示例中使用的语法感到有些困惑在网上找到。例如,我们将operator<<重载视为简单自定义类的非成员函数:

#include <fstream>

class Example {
public:
    int first;
    int second;
};

// I found this kind of operator on the Internet
std::ofstream& operator<< (std::ofstream& out, Example obj) {
    out << obj.first << endl << obj.second;
    return out;
}

int main() {
    Example a={1,2};
    std::ofstream out;
    out.open("test");
    out << a;
    out.close();   
}

我不明白为什么它应该让std::ofstream&正常工作。我尝试使用以下运算符

void operator<< (std::ofstream& out, Example obj) {
     out << obj.first << endl << obj.second << endl;
}

它也有效。我的意思是,out << obj;可以解释为operator<< (out , obj);吗?为什么它必须返回一些东西,因为我传递了对std::ofstream对象的引用?

当我尝试将operator=重载写为自定义类的成员函数时出现了同样的疑问,如下面的简单示例

class Custom{
public:
    int up;
    int down;

    Custom& operator= (Custom a) {
         up=a.up;
         down=a.down;
         return *this;
    }
};

我使用了复制交换习惯用于赋值运算符,因此不要过多地考虑运算符定义,它只是一个例子。再次,写作

Custom obj1, obj2;
obj1 = obj2;

因为我可以将obj1 = obj2;解释为obj1.operator=(obj2),为什么需要返回类型Custom&而不是void

4 个答案:

答案 0 :(得分:2)

如果您希望能够将operator<<链接在一起,则必须使用返回类型(比std::ostream&更好std::ofstream&,因此您可以将其用于std::cout并且也喜欢)。

out << a << b;
(out << a) << b;
^^^^^^^^^^
lhs has to be a stream

对于赋值运算符,原因基本相同。 C ++语法允许您编写许多需要返回类型的表达式,例如:

Custom obj1, obj2, obj3;
(obj1 = obj2) + obj3 ... // assign obj2 to obj1 and work with that...

答案 1 :(得分:1)

返回引用允许您链接运算符,如

std::cout << e1 << e2;

答案 2 :(得分:1)

返回引用而不是void,可以像

一样编写
out << obj1 << obj2 << obj3;

对于operator=,您可以写

obj1=obj2=obj3;

答案 3 :(得分:1)

您可以编写类似cout << "First operand" << "Second operand"的内容,因为第一个操作数返回对ostream的引用,第二个操作数适用于此引用。 operator=的工作方式相同。您可以撰写a = b = c,但也可以将其放在if (a = b)while (a = b)内。这可以使您的代码更短,但有点危险。