c++類型轉換函數的麻煩及解決方法

c++如同C語言一樣, 有語言本身的隱式類型轉換。如將char轉換成int int轉換爲double等 c++還可以將double轉換成int 即向下轉換。

這是語言本身提供的,我們不能控制。但是對於我們自己寫的類卻可以自己控制。有兩種函數提供這種類型的轉換:隱式類型轉換操作符與單一變量構造函數。

儘量不要提供這兩種函數

原因:

1.對於隱式類型轉換操作符:

它可能在你不知道的時候就調用了,得到與你預期不一樣的結果。

如下面一個類:

class Rational

{

public:

...

operator double() const;

};

函數會在以下情況被調用

Rational r(1,2);

double d=0.5*r;

但是,若你想要輸出1/2.你可能會這樣寫:

Rational r(1,2);

cout<<r;

假設你沒有定義operator<<  ,依然可以編譯通過,編譯器會找到operator double函數來完成輸出,顯然結果將是double,並不是你想要的結果。

解決方法:以另一個功能相同的函數來代替隱式類型轉換操作符。

如:利用一個函數asDouble來封裝operator double 

結果如下:

cout<<r;//錯誤

cout<<r.asDouble;//正確

2.單自變量的構造函數,即只有一個參數的構造函數或者只有一個需要傳參的參數,其他參數都有默認值的構造函數。

如下面的例子:

template<class T>

class array

{

array(int size);

array(int lowbound,int hbound);

...

};

第一個構造函數可以作爲一個類型轉換函數。

例考慮一個用來對array<int>做比較的函數

bool operator==(const array<int>& l,const array<int>& h);

array a(10);

qrrqy b(10);

..

for(int i=0;i<10;i++)

{

if(a==b[i])//這裏不小心寫成了a

...

};

編譯器對上述代碼並不報錯,編譯器會將b[i]隱式轉換成static_cast<array<int> >b[i];

變成了a與一個臨時對象進行比較。

顯然,這並不是你所需要的。

解決辦法:

1.在構造函數那裏加上explicit關鍵字,可以使得構造函數不能隱式轉換。

2.將size寫成一個類,因爲規定:沒有任何一個轉換程序可以內含一個以上的“用戶指定轉換行爲”。

總結:對“定製的類型轉換函數”要提高警惕。

上述例子摘錄自more effective c++


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章