重载流操作符为什么必须用引用

转载 2011年07月20日 11:26:12

http://hi.baidu.com/%C8%CE%C5%E0%BB%A8/blog/item/1d3a1cf583a97e34bc310918.html


在C++中,流操作符(>>)是经常要被重载的,一般的形式是这样的:

class CObj
{
    ...
};

std::ostream& operator << (std::ostream& strm, const CObj& objA)
{
    ...
    return strm;
}

我们经常使用流的引用,而不是直接把一个流作为值传送,原因主要考虑到流是一种资源,如果作为值传送,出现了对资源的复制,释放的时候很麻烦,而且可能出现两个流同时操作一个文件的情况。但是这个原因只能说是我们用流作为引用而不是值传送的一个逻辑或性能限制,不是语法限制,也就是说,我们是可以硬把流作为一个值传送过来的。

也就是说,我们实际上可以这样写的:

class CObj
{
    ...
};

std::ostream operator << (std::ostream strm, const CObj& objA)
{
    ...
    return strm;
}

但是这样写了以后,编译器(Visual C++ 7.0)会报告编译时错误,类型不匹配。为什么会这样?难道是语法上有限制吗?

事实上是语法上并没有这样的限制说重载流符号的时候一定要用引用方式来传递流,事实上是,我们在传递参数的任何时候都必须用引用方式传递流,或者指针(这就和引用没区别了),原因在于:流的类体系结构中,不管是哪个流,都只有一个接收指针作为参数而且没有用explicit声明拷贝构造函数,也就是说,所有的流,都没有提供可以用另外一个流作为值传送参数的拷贝构造函数。这是不使用引用传送流引起语法错误的原因。

如果我们使用值传送来传递一个流给函数,那么在函数里要生成一个该流的临时变量,生成临时变量的时候,就要调用对应的拷贝构造函数,并且这个拷贝构造函数必须是以一个值传送的流作为参数的——但是流就是没有这样的拷贝构造函数。

结果,编译时错误就产生了!

 

WHY STREAM ONLY CAN BE PASSED AS REFERENCE WHEN OVERLOAD A STREAM OPERATOR?

In C plus plus, stream opeator (>>) is offen overloaded, and we always overload it like this:


class CObj
{
    ...
};

std::ostream& operator << (std::ostream& strm, const CObj& objA)
{
    ...
    return strm;
}


When we pass stream as a parameter to a function, we will use reference, not value passed,  the main reason is that stream is a kind of resource, if we pass it as a valued passed parameter, the programme will copy the resource, and then the resource which is copied twice may be releaseed twice too, and this, may cause trouble. For the more, copying a stream also can cause two or more streams write to one file at same time. But this is only a reason in the logic, not a grammer rule, that is to say, we can pass stream as valued passed parameter, althought this is wrong:

class CObj
{
    ...
};

std::ostream operator << (std::ostream strm, const CObj& objA)
{
    ...
    return strm;
}

If we really write like this, the compiler (I use Visual C++ 7.0) will report a compile-time error, type mismatch or construcor not found (I can't remember the actual one). Why? Is it a grammer rule?

In fact, it is not a grammer rule that you can not pass stream as value when you overload the stream operator, in fact, it is a grammer rule that we MUST pass stream as reference or pointer (pointer is reference, for the compiler) when we want to pass stream as a parameter to a function. The reason is: In the structure of stream's class, no matter which stream it is, it only have one copy constructor without explicit which can accept a pointer of stream, that is to say, all the streams, do not have a copy constructor which can accept another stream as a value. This is the reason which cause an error if we pass a stream as a value.

If we pass a stream as a value to a function, the function will create a temporer vaiable, the temperor variable is created by a copy constructor which can accept a stream as value, but all the streams do not have such a copy sonsturcutor.

Compile-time error occur as a result! 

相关文章推荐

引用及操作符的重载

引用是C++的概念,属于C++编译器对C的一个扩展 引用可以看做是一个已经定义的变量的别名 语法: Type &b = a; 引用是不能修改的,所以在声明时必须初始化。并且其还占有内存空间。可...

好久没有写操作符重载了 自己重新写了个 温习了一下细节 温习友元 this const 引用

#include using namespace std; class Point { public: Point(int _x, int _y) : x(_x), y(_y) ...

C++ 运算符流操作符重载和友元--笔记

/************************************************************************************************ *...

C++ 操作符重载

  • 2013年05月30日 01:47
  • 1KB
  • 下载

操作符重载之解引用与箭头操作符

箭头操作符与众不同。它可能表现得像二元操作符一样:接受一个对象和一个成员名,对对象解引用以获取成员。不管外表如何,箭头操作符不接受显式形参。这里没有第二个形参,因为 -> 的右操作数不是表达式,相反,...

c++课件(5)操作符重载1

  • 2017年07月29日 14:02
  • 553KB
  • 下载

操作符重载

  • 2012年11月01日 13:02
  • 756B
  • 下载

C++ Primer学习笔记——$14 操作符重载、函数对象及类类型转换

题记:本系列学习笔记(C++ Primer学习笔记)主要目的是讨论一些容易被大家忽略或者容易形成错误认识的内容。只适合于有了一定的C++基础的读者(至少学完一本C++教程)。  作者: tyc611,...
  • whycold
  • whycold
  • 2011年01月19日 15:09
  • 728

重载操作符与转换.txt

  • 2015年12月23日 21:00
  • 2KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:重载流操作符为什么必须用引用
举报原因:
原因补充:

(最多只允许输入30个字)