2011-08-21 91 views
0

我對C++如何在需要做數學時強制類型轉換有疑問。鑄造上出乎意料的行爲

下面的代碼就是這樣(即只有投射爲int而不投射爲雙倍)才能正常工作和構建。如果我定義ENABLE_DOUBLE_CAST不會構建並投訴operator*。你知道爲什麼嗎?

我的疑惑是2:

  1. 爲什麼不操作轉換爲加倍,但是它使用了一個雙間的乘法爲int。是因爲隱含演員嗎?
  2. 爲什麼WITH轉換使雙重啓用(增加更清晰的語法),沒有考慮到?

感謝

AFG

class CA{ 
    int _m; 
public: 
    CA(int a, int b){ 
    _m=a*b; 
    } 
    operator int(){ 
     std::cout<< "(CA int cast)" ; 
     return _m; 
    } 
#ifdef ENABLE_DOUBLE_CAST 
    operator double(){ 
     std::cout << "(CA double cat)"; 
     return 2.3 * _m; 
    } 
#endif 
}; 

int main(int argc, const char** argv){ 
    CA obj_2(10,20);     

    double total_1 = 100.0 * obj_2; 
    double total_2 = obj_2 * 100.0; 
    return 0; 
} 
+0

您已經聽說過用戶定義的轉換,但沒有用戶定義的'operator *'?你需要定義後者。事實上,你必須定義兩個版本的'operator *'。 – Nawaz

回答

3

爲什麼不操作轉換爲加倍,但是它使用了一個雙間的乘法爲int。是因爲隱含演員嗎?

是的,這是真的。
它使用operator int()obj_2轉換爲int,然後使用內置operator*(double, int)

爲什麼跟投給double啓用(加入更加清晰的語法)並沒有考慮到?

當您同時提供operator double()operator int()爲您的類,它創建了一個不確定性,是否obj_2轉換爲intdouble因爲有兩個內置的運算符重載,它可以使用,即:

operator*(double, int) 
operator*(double, double) 

建議:
你應該重載operator*你的類,如果你想避免這名p由此產生的隱含轉換和模糊性。

operator*(double,CA) and 
operator*(CA,int) 
+0

嗨Als。謝謝你清楚的解釋。我總是認爲C++內置的二元運算符僅限於WITH THE SAME TYPE的參數,所以運算符*(double,double)或運算符*(int,int)。基本上你是說C++也提供了不同類型的C++? –

+0

@Abruzzo Forte e Gentile:是所有內置類型的運算符運算符都隱含在C++中。只有當其中一個操作數是自定義類時,纔可以重載它們。 –

1

的原因是,與兩個蒙上你有曖昧的代碼,編譯器無法決定是否要使用INT投或雙投,都是合法的。

關於隱式投射的規則很複雜,我不打算在這裏試着重複它們(它會從字面上用頁面和頁面來覆蓋所有內容)。但是如果它普遍同意爲你的類添加隱式類型轉換是一個壞主意,因爲你所看到的那些含糊不清的問題。如果你想用操作符*來使用CA,那麼最好爲你的類定義操作符*。例如。

CA operator*(CA x, CA y) 
{ 
    ... 
} 

CA operator*(CA x, int y) 
{ 
    ... 
} 

CA operator*(CA x, double y) 
{ 
    ... 
} 

CA operator*(int x, CA y) 
{ 
    ... 
} 

CA operator*(double x, CA y) 
{ 
    ... 
} 
+0

嗨,約翰。閱讀其他文章,關於避免它的一般規則是好的。如果你不介意的問題當這些演員操作員可能有點幫助時,是否有任何情況?如果一般來說他們必須避免,爲什麼他們仍然在附近?任何用例都置於你的頭腦之上? –

+0

我認爲這個用例是一個轉換爲布爾值,假設用你的'CA'類,你想用它作爲布爾值,就像這個'CA ca = ...;如果(ca)...'。如果不引入大量模糊或令人驚訝的轉換,實際上很難做到。它可以完成,它被稱爲_safe布爾idiom_,這是一個很好的鏈接更多閱讀http://www.artima.com/cppsource/safebool.html – john

+0

謝謝先生!非常感激! –