2011-09-19 37 views
0

考慮下面的例子,行int a = objT + 5;給出了模棱兩可的轉換,它使用兩種方式處理,使用我認爲不需要的顯式轉換,並用成員函數替換轉換運算符的使用。在這裏,我的問題變成了你仍然使用轉換操作符還是根本不使用轉換操作符?何時使用轉換運算符?

class Testable { 

public: 
    Testable(int val = 0):x(val){} 

    operator int() const { return x; } 
    operator double() const { return x; } 

    int toInt() { return x; } 
    double toDouble() { return x; } 

private: 
    int x; 
}; 

int main() 
{ 
    Testable objT(10); 

    // ambiguous conversion 
    int a = objT + 5; 

    // why to use explicit cast when 
    // the conversion operator is for to handle 
    // this automatically 
    int b = static_cast<int>(objT) + 5; 

    // member functions 
    int c = objT.toInt() + 5; 
} 

回答

2

請注意,int d = objT;是明確的,因爲double e = objT;在這裏,編譯器可以明確地選擇一個轉換運算符,因爲左側類型和來自那些轉換運算符的返回類型之間完全匹配。

來自objT + 5(也注意:long f = objT;也不明確)的模糊轉換結果。問題在於你已經拿走了編譯器無需執行消歧的基本信息。

如果你擺脫了這些轉換操作符,問題就消失了。由於底層的數據成員是int,我建議擺脫operator double()

0

對於您的特定情況,您可以將轉換提供爲double,因爲它具有標準轉換爲int。但是,隱式轉換通常會造成更多的傷害而不是幫助。如果你使用它們,那麼避免同時從int(你的非顯式構造函數)和int類型轉換,我認爲這是你當前問題的根源。

0

您不需要隱式轉換爲double。您總是返回十進制值,編譯器可以組合多個隱式轉換運算符。

如果您的int類型的私有屬性x是雙精度型,我會建議不要使用向int的隱式轉換,因爲它會導致精度損失。

+0

所以,我認爲現在歸結爲有一個轉換函數爲int或double和一個成員函數爲轉換的其他選擇取決於類的數據成員。或者我可以完全擺脫轉換運營商,以避免任何明確的轉換。 – cpx

0

此問題與我的相似,whether is it possible to change the precedence of implicit conversion operators。不幸的是,沒有令人滿意的解決方案,隱式轉換中沒有優先級。

一種解決方案是具有額外的過載(一個或多個),以歧義函數或運算符,在你的情況下,它們操作者+(常量可測試&,int)和操作員+(常量可測試&,雙面)。

另一種解決方案是隻留下一個隱式轉換,在您的情況下,整數一個將是最好的。

當您迫切需要自動轉換爲給定類型時,僅使用隱式轉換。顯式toInt,toDouble函數更好,他們澄清了代碼,並沒有隱藏潛在的陷阱。對一元構造函數使用explicit關鍵字,它們通過該構造函數阻止隱式轉換。

不,不可能鏈隱式轉換,既不是運算符也不是構造函數。 C++標準規定只有1個隱式轉換可以在轉換序列中。