2010-03-13 41 views
0

嗨我有這樣的代碼,我認爲朋友重載運算符和轉換運算符都有類似的功能。但是,爲什麼在這種情況下調用了朋友重載運算符?規則是什麼?爲什麼朋友重載運算符在這種情況下首選轉換運算符

非常感謝!

class A{ 

    double i; 
public: 
    A(int i):i(i) {} 
    operator double() const { cout<<"conversion operator"<<endl;return i;}       // a conversion operator 
    friend bool operator>(int i, A a);       // a friend funcion of operator > 
}; 

bool operator>(int i, A a){ 
    cout<<"Friend"<<endl; 
    return i>a.i; 
} 
int main() 
{ 
    A aa(1); 
    if (0 > aa){ 
     return 1; 
     } 
} 

回答

4

調用超載的operator>不需要轉換。爲了調用內置的operator>,需要進行一次轉換(用戶定義的轉換運算符:過載分辨率優先選擇所需的轉換次數較少,因此使用超載的operator>

請注意,如果您要改變的定義你的超載operator>是,例如:

friend bool operator>(double i, A a); 

,你會得到一個編譯錯誤,因爲無論是超載operator>和內置operator>需要一個轉換,編譯器將無法解決歧義。

+0

或者,如果他將比較更改爲'0L> aa',他也會收到編譯錯誤。所以無論如何他目前的解決方案是不可接受的,我認爲=) –

1

我不是聲稱我的答案是由標準支持,但讓我們從邏輯上思考它。

當你點擊這一行:

0 > aa 

你有兩個選擇。您可以致電所提供的運營商:

friend bool operator>(int i, A a); 

這是100%兼容,或者您​​可以做兩次轉換以達到目的地!你會選哪一個?

+0

這將是有趣的知道什麼是未定義的'A(INT我):我(我){} – UncleBens

+0

對不起,這是一個錯誤:) – AraK

+0

@UncleBens只是爲了記錄。我想到的是'A(int i):i(i){}'相當於'A(int i){i = i;這當然不是。 – AraK

0

如果添加一個轉換運算符,那麼類型A的對象可能會在最不經意的時候轉換爲double。

一個好的程序不能爲他的類意外使用提供一種方法,並且轉換運算符爲類在整個無意的情況下使用開闢了運行的機會(通常情況下你會希望編譯時錯誤不是因爲自動類型轉換)。

因此,轉換運算符(和單參數構造函數)應該小心處理,因爲編譯器可能會在最不經意的時候進行轉換。

0

它被稱爲是因爲它在表達式0 > aa的上下文中是完全匹配。事實上,很難弄清楚你是如何提出「爲什麼」的問題的。根據邏輯,如果朋友不是在這種情況下被調用,你會期望一個「爲什麼」的問題。

如果將表達式更改爲0.0 > aa,則調用將變得模糊,因爲中性路徑會比其他路徑更好。