1. 程式人生 > >c++型別轉換函式的麻煩及解決方法

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