现在的位置: 首页 > 综合 > 正文

while(cin>>val)的原理浅析

2018年05月05日 ⁄ 综合 ⁄ 共 1181字 ⁄ 字号 评论关闭

       今天看书的时候看到代码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类型。

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

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

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

#include<iostream>
using namespace std;
class A
{
public:
    A(){}
    ~A(){}
    operator void *()const
    {
        cout<<"cast to void*; ";
        return (void *)this;
    }
     bool operator!() const
    {
        cout<<"cast to bool; ";
        return true;
    }
};

int main()
{
    A a;
    if(a) cout<<"first"<<endl;
    if(!a) cout<<"second"<<endl;
    return 0;
}

        运行以上程序,结果为cast to void*; first和cast to bool; second。结果表明,if(a)隐式调用了operator void *()函数,if(!a)隐式调用了bool operator!()函数。

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



The End

抱歉!评论已关闭.