C++隱式類類型轉換

C++能夠定義如何將其餘類型的對象隱式轉換爲咱們的類類型或將咱們的類類型的對象隱式轉換爲其餘類型。爲了定義到類類型的隱式轉換,須要定義合適的構造函數。ios

說明:能夠用單個實參來調用的構造函數定義了從形參類型到該類類型的一個隱式轉換。app

 

class Sales_item
{
public:
    Sales_item(const string &book = "") : isbn(book), units_sold(0), revenue(0.0) {}
    Sales_item(istream &is);
};

這兩個構造函數都定義了一個隱式轉換。所以,在期待一個Sales_item類型對象的地方可使用一個string或一個istream對象。函數

 

string null_book = "9-999-99999-9";
item.Same_isbn(null_book);

這段代碼使用一個string類型對象做爲實參傳遞給Sales_item的Same_isbn成員函數,該成員函數期待一個Sales_item對象做爲實參。編譯器將使用接受一個string的構造函數從null_book生成一個新的Sales_item對象。新生成的(臨時的)Sales_item對象被傳遞給Same_isbn。測試

 

item.Same_isbn(cin);

這段代碼將cin對象隱式轉換爲Sales_item對象,這個轉換執行接受一個istream的構造函數。這兩個Sales_item是臨時對象,一旦Same_isbn結束,就不能再訪問它。ui

 

下面看一個例子:http://blog.csdn.net/vagrxie/article/details/1586340spa

 1 #include <string>
 2 #include <iostream>
 3 using namespace std;
 4 
 5 class Fruit                                //定義一個類,名字叫Fruit
 6 {
 7     string name;                        //定義一個name成員           
 8     string colour;                        //定義一個colour成員
 9 
10 public:
11     bool isSame(const Fruit &otherFruit)   //期待的形參是另外一個Fruit類對象,測試是否同名
12     {
13         return name == otherFruit.name;
14     }
15     void print()              //定義一個輸出名字的成員print()
16     {
17         cout<<colour<<" "<<name<<endl;
18     }
19     Fruit(const string &nst,const string &cst = "green"):name(nst),colour(cst){}  //構造函數
20 
21     Fruit(){}
22 };
23 
24 int main(void)
25 {
26     Fruit apple("apple");
27     Fruit orange("orange");
28     cout<<"apple = orange ?: "<<apple.isSame(orange)<<endl;  //沒有問題,確定不一樣
29     cout<<"apple = apple ?:"<<apple.isSame(string("apple"))<<endl; //用一個string作形參?
30 
31     return 0;
32 }

咱們用string("apple")類型做爲一個期待Fruit類型形參的函數的參數,結果是正確的。當把構造函數colour的默認實參去掉,也就是定義一個對象必需要兩個參數的時候,文件編譯不能經過。Fruit apple("apple")其實也已經有了一個轉換,從const char *的C字符串格式,轉爲string。但apple.isSame("apple")這樣調用確定是錯的,必需要用string()來先強制轉換,而後系統才知道幫你從string隱式轉換爲Fruit。固然你也能夠顯式幫它完成,apple.isSame(Fruit("apple"))。.net

 

能夠經過將構造函數聲明爲explicit,來防止在須要隱式轉換的上下文中使用構造函數。explicit關鍵字只能用於類內部的構造函數聲明上。在類的定義體外部所作的定義再也不重複它。雖然不能隱式轉換了,但顯式轉換仍是能夠的,例如:apple.isSame(Fruit("apple"))。code

說明:對象

(1)顯式使用構造函數只是終止了隱式地使用構造函數。任何構造函數均可以用來顯式地建立臨時對象。blog

(2)一般,除非有明顯的理由想要定義隱式轉換,不然,單形參構造函數應該爲explicit。將構造函數設置爲explicit能夠避免錯誤,而且當轉換有用時,用戶能夠顯式地構造對象。

(3)將構造函數設置爲explicit的好處是能夠避免因隱式類型轉換而帶來的語義錯誤,缺點是當用戶的確須要進行相應的類型轉換時,不能依靠隱式類型轉換,必須顯式地建立臨時對象。

相關文章
相關標籤/搜索