【问题标题】:Operator overload doubts运算符重载疑虑
【发布时间】:2016-06-11 15:03:23
【问题描述】:

我试图编写一些运算符重载函数,尤其是 << 运算符,以将其与自定义类和 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&amp; 才能正常工作。我尝试使用以下运算符

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

而且效果也很好。我的意思是,out &lt;&lt; obj; 不能解释为 operator&lt;&lt; (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&amp; 而不是void?

【问题讨论】:

标签: c++ class operator-overloading operators


【解决方案1】:

如果您希望能够将operator&lt;&lt;s 链接在一起,则必须使用返回类型(std::ostream&amp; 比std::ofstream&amp; 更好,因此您也可以将它用于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...

【讨论】:

  • (obj1=obj2)+obj3 不应该是 (obj1=obj2)=obj3 吗?无论如何,谢谢,这很有帮助
  • @luigi 我只是选择了operator+(您的代码中没有定义)而不是operator=。没关系。不过,将= 链接在一起可能更常见。
  • 哦,好吧,虽然你的意思类似于@songyuanyao 在下面写的内容。
【解决方案2】:

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

std::cout << e1 << e2;

【讨论】:

    【解决方案3】:

    返回一个引用而不是void,让写like成为可能

    out << obj1 << obj2 << obj3;
    

    operator=可以写

    obj1=obj2=obj3;
    

    【讨论】:

    • 现在很清楚,甚至没有考虑链接的可能性。谢谢
    【解决方案4】:

    你可以写像cout &lt;&lt; "First operand" &lt;&lt; "Second operand" 这样的东西,因为第一个操作数返回对ostream 的引用,而第二个操作数使用这个引用。 operator= 工作方式相同。你可以写a = b = c,也可以写在if (a = b)或者while (a = b)里面。这可以使您的代码更短,但有点危险。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-19
      • 1970-01-01
      • 2011-06-21
      • 2012-09-14
      • 2011-04-08
      • 2012-03-10
      相关资源
      最近更新 更多