为什么我们需要在重载>>时返回对istream / ostream的引用和<<运营商?

时间:2015-03-07 08:41:47

标签: c++

如果我不返回dindout会发生什么,实际上我正在阅读一本书,其中作者返回流引用

istream & operator>>(istream &din,vector &a)
{
    for(int i=0;i<size;i++)
    din>>a.v[i];
    return din;
}

ostream & operator<<(ostream &dout,vector &a)
{
    dout<<"("<<a.v[0];
    for(int i=1;i<size;i++)
    dout<<", "<<a.v[i];
    dout<<")";
    return dout;
}

4 个答案:

答案 0 :(得分:7)

原因是几个事实的组合。

  1. 您希望能够像

    中那样链接输入和输出操作
    in  >> x >> y;
    
    out << z << std::precision(10) << t << std::endl;
    

    因此您必须再次返回允许operator<<的内容。

  2. 由于您希望运营商处理任何istream,即从std::istream派生的任何对象,您无法定义

    operator<<(istream_type, object);    // take istream by value
    

    因为这只适用于特定的istream类型istream_type,而不适用于通用的istream。为此,必须使用多态,即获取引用或指针(它将是从std::istream派生的类的引用或指针)。

  3. 由于您只有对istream的引用,因此无法返回istream对象本身(可能是operator<<定义中未定义的类型)但仅返回引用你有。

    可以通过定义operator<<一个template并按值返回istream_type来解决此限制,但这需要istream类型具有复制构造函数,它可能没有充分的理由。

  4. 为了唤起多态性,原则上可以使用指针(对流)而不是引用。但是,operator<<(stream*,const char*)是 在C ++中不允许(至少一个操作数必须是类或枚举类型)。

    因此,对于流指针,必须使用函数调用语法,然后使用C风格fprintf(stream*, args...)返回。

    此外,指针可以为null或悬空,实际上它们是默认状态(在没有初始化程序时声明),而引用可以假定为有效(不能在没有初始化程序的情况下声明)。

答案 1 :(得分:3)

在这种情况下,当返回引用时,您可以在链中组合运算符。例如

std::cout << "Hello " << "Rajat Verma";

这相当于操作员的以下调用

operator <<( operator <<( std::cout, "Hello" ), "Rajat Verma" );
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
              returns reference to std::cout 

答案 2 :(得分:3)

还有一件事是ostream和istream标准对象(如cout和cin)使用私有拷贝构造函数,因此它们应该通过引用而不是通过值返回

答案 3 :(得分:-1)

键入时:  cout&lt;&lt;向量; cout有ostream的类型所以当你使用&#34; &LT;&LT; &#34;它需要返回一个带有ostream类型的争论才能让cout工作