<<<<< />>运算符重载和输入/输出函数

时间:2015-10-28 14:26:22

标签: c++

如果有人能向我解释重载输入/输出操作符之间的区别,我真的很感激,例如:

friend ostream& operator<<(ostream& ost, const myClass& obj) {
    return ost << obj.x << obj.y;
}

和输出/输入功能如下:

void Output(ostream& ost) {
    ost << x << y;
}

它们用于什么,例子等等。一切都是可以接受的。谢谢!

4 个答案:

答案 0 :(得分:4)

重载<<运算符将允许您链接输出操作:

myClass a, b;

...

cout << a << ' ' << b;

使用您的备用实现,您必须写:

myClass a, b;

...

a.Output(cout);
cout << ' ';
a.Output(b);

第一个版本可以更轻松地快速查看输出的格式。它也是在C ++中使用流的标准方法。

答案 1 :(得分:4)

主要区别在于,如果你超载&#34;流操作符&#34;那么你的类可以被模板函数使用。

使用标准命名的输出方法可以起到类似的作用,但是使用流操作符还有一个额外的好处,即它也可以为非类类型定义(即,您可以定义将整数输出到流的含义,但是你不能为整数定义方法.output

答案 2 :(得分:3)

运营商&lt;&lt;如果您想这样调用,则使用它:cout << myObject ...如果您想这样调用它,可以使用输出:myObject.Output(cout);(但是,谁会?)。

但我怀疑你在这里发生的是两种竞争方式来写&lt;&lt;&lt;&lt;操作

第一个是上面的那个,带有friend关键字。

这是另一个版本:

void myClass::Output (ostream& ost)
{
    ost << x << y;
}

ostream& operator<<(ostream& ost, const myClass& obj) 
{
    obj.Output (ost); return ost;
}

第二个版本通常被认为更好,因为它避免使用friend,这被视为安全风险。允许非成员函数访问私有部分(因此推理)会降低该私有部分的安全性。

这是一篇堆栈溢出文章,详细讨论了这个问题: Should operator<< be implemented as a friend or as a member function?

......以及&#34;何时使用朋友&#34;的一般哲学这里讨论:https://softwareengineering.stackexchange.com/questions/105766/c-to-friend-or-not-to-friend

我对此的看法是使用friend并不邪恶,但我不需要它时就避免使用它。而在这里,它不是,正如第二个版本所示。

答案 3 :(得分:1)

在重载任何这些之间确实没有区别(从技术角度来看)。事实上,即便是那些并不特别。它们只是可过载的操作员 - 左移操作员和右移操作员。一般来说,重载运算符的原因是提供更好的语法,特别是基于感知的直觉性,特别重载这些运算符的原因。

传统上,operator <<被重载到发送某些东西(并称为插入运算符),operator >>重载到从其他东西中提取某些内容 - 并称为提取运算符。在大多数情况下,您要发送的某些output stream,例如std::cout,而您从中提取的内容是输入流,例如std::cin 。考虑到这一点,std::cout << "Hello\n"很容易理解为将“Hello \ n”字符串发送到输出流,在std::cout的情况下通常具有在控制台窗口上打印它的效果。

然而,人们可以绝对地交换那些重载,并且重载&gt;&gt;作为插入操作符。在后一种情况下,打印将采用std::cout >> "Hello\n"的形式。不会对编译器的观点产生任何影响,但对程序员来说不那么直观 - 那些&gt;&gt;和&lt;&lt;像箭一样。

可以为此选择完全不同的运营商。例如,->也是一个可重载的运算符,选择它作为提取运算符会很棒。请考虑一下:std::cin -> str。箭头更加明确。不幸的是,没有可重载的运算符<-,因此缺乏对称性。

另外,必须记住,发明了运算符重载是为了允许C ++程序定义新实体而不引入新的保留语言结构。如果C ++是一种全新的语言,并且不会站在C的肩膀上,那么最终结果可能会非常不同。