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++