在判断文件打开成功与否或是连续从流中读取数据时,就要用到对流对像的操作,比如if(!cin) 或是 whie(cin) 等等。
代码 while(cin>>val),我们都知道 cin 是一个流对象,而>>运算符返回左边的流对象,也就是说 cin>>val 返回 cin,于是 while(cin>>val)就变成了 while(cin),问题就变成了一个流对象在判断语句中的合法性。
不管是 while(cin)还是 if(cin),都是合法的,为什么呢?我们自己定义一个类,然后定义该类的对象,然后使用 if 语句来判断它是不合法的。这说明,流对象具有某种转换函数,可以将一个流对象转换成判断语句可以识别的类型。
打开 iostream.h 文件,找到 cin 的定义,发现是来自于 istream.h,其中的模板类basic_istream 继承自 basic_ios,打开 basic_ios 的定义,发现它有两个重载函数。operator void *() const 和 bool operator!() const。这两个函数使得流对象可作为判断语句的内容。
operator void*() const //转化函数
{
return this->fail() ? 0 : const_cast<basic_ios*>(this);
}
bool operator!() const
{
return this->fail();
}
结论:
1、operator void () const; 函数在 while(cin)或是 if(cin)时被调用,将流对象转换成 void 类型。
2、bool operator!() const; 函数在 while(!cin)或是 if(!cin)时被调用,将流对象转换成 bool 类型。
需要指出的是,上述两个类型转换都是隐式的。
因此,可以简单的理解调用过程为:
while(cin) =====> while(!cin.fail()) //while the stream is OK
while(!cin) =====> while(cin.fail()) //while the stream is NOT OK
简单测试:
#include<iostream>
using namespace std;
class A {
public:
A() {}
~A() {}
operator void * () const {
return (void*)this;
}
bool operator!()const {
return true;
}
};
int main() {
A a;
if (a) cout << "operator void * () const" << endl;
if (!a) cout << "bool operator!()const" << endl;
system("pause");
return 0;
}
输出结果:
通过调试可以看到if(a)调用的就是operator void * () const这个函数
if(!a)调用的bool operator!()const。