while(cin)和while(!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的定义,发现它继承自ios_base,再次定位到ios_base类,发现它有两个重载函数。operator void *() const和bool operator!() const。这两个函数使得流对象可作为判断语句的内容。

        operator void *() const;函数在while(cin)或是if(cin)时被调用,将流对象转换成void *类型。

        bool operator!() const;函数在while(!cin)或是if(!cin)时被调用,将流对象转换成bool类型。

          C++中basic_ios.h中的函数定义如下:

/**
 *  @brief  The quick-and-easy status check.
 *
 *  This allows you to write constructs such as
 *  "if (!a_stream) ..." and "while (a_stream) ..."
*/
operator void*() const
{ return this->fail() ? 0 : const_cast<basic_ios*>(this); }

bool operator!() const
{ return this->fail(); }

        因此,可以简单的理解调用过程为:

               while(cin)  =====> while(!cin.fail())              //while the stream is OK
               while(!cin) =====> while(cin.fail())               //while the stream is NOT OK

        需要指出的是,上述两个类型转换都是隐式的。

        既然我们找到了while(cin)合法的原因,自然需要试验一下。

        我们定义一个类A,在A中定义上述两个函数,然后定义A的一个对象a,使用if(a)和if(!a)来验证一下。代码如下:

[cpp]  view plain copy
  1. #include<iostream>  
  2. using namespace std;  
  3. class A  
  4. {  
  5. public:  
  6.     A(){}  
  7.     ~A(){}  
  8.     operator void *()const  
  9.     {  
  10.         cout<<"cast to void*; ";  
  11.         return (void *)this;  
  12.     }  
  13.      bool operator!() const  
  14.     {  
  15.         cout<<"cast to bool; ";  
  16.         return true;  
  17.     }  
  18. };  
  19.   
  20. int main()  
  21. {  
  22.     A a;  
  23.     if(a) cout<<"first"<<endl;  
  24.     if(!a) cout<<"second"<<endl;  
  25.     return 0;  
  26. }  
         运行以上程序,结果为cast to void*; first和cast to bool; second。结果表明,if(a)隐式调用了operator void *()函数,if(!a)隐式调用了bool operator!()函数。

       上述两个函数其实是操作符的重载过程。使用这种重载函数,我们就可以像使用cin一样,用if语句对我们的对象做判断了。

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值