while(cin>>a)的原理


>>運算符返回的是流對象的引用,那么題目就變成了 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類型。

///當流處於goodbit狀態時,讀入成功碼,返回cin地址,並轉換為void*型,繼續循環 
operator void * () const
     ///流的狀態由>>操作符調用ios改變,當讀到eof或者輸入不符合所寫入的類型時設置badbit和failbit 
     if (state & (badbit | failbit)) ///一種直觀的寫法 
         return 0; ///當流處於badbit或failbit狀態時,返回0,循環停止 
     return ( void *) this ; ///返回的是cin,相當於while(cin) 
}

 

需要指出的是,上述兩個類型轉換都是隱式的。

       既然我們找到了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語句對我們的對象做判斷了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM