2013-10-22 49 views
-1

這裏我試圖重載關係運算符。當我米appyling重載函數類的兩個對象然後它是工作,但是當I M把它應用到一個對象和浮點值然後它給我錯誤,指出「從「double'to‘距離’轉換ambigous」。 請幫忙。如何使用用戶定義的數據類型對定義的數據類型進行操作?

#include <iostream> 

using namespace std; 

class Distance 
{ 
    int iFeet; 
    float fInches; 
public: 
    Distance(const float); 
    Distance(const int = 0, const int = 0); 
    bool operator >(const Distance); 
}; 

Distance::Distance(const float p) 
{ 
    iFeet = int(p); 
    fInches = (p - iFeet) * 12; 
} 

Distance::Distance(const int a, const int b) 
{ 
    iFeet = a; 
    fInches = b; 
} 

bool Distance::operator>(const Distance dd1) 
{ 
    if (iFeet > dd1.iFeet) 
     return true; 
    if (iFeet == dd1.iFeet && fInches > dd1.fInches) 
     return true; 

    return false; 
} 

int main() 
{ 
    Distance D(1, 6), D2(1, 8); 
    if (D > D2) 
     cout << "D is gtreater than D2" << endl; 
    else 
     cout << "D2 is greater than D" << endl; 

    if (D > 5.6) 
     cout << "D is greateer" << endl; 
    else 
     cout << "D is not greater" << endl; 
    return 0; 
} 

回答

0

你超載operator >只能兩個Distance對象之間的比較。

左手側已經是DistanceD

右手邊是一個double5.6

你的編譯器試圖轉換doubleDistance,但沒有合適的構造函數。有一個構造函數需要一個const float和一個需要零個,一個或兩個const int s;編譯器無法在兩者之間進行選擇,因此出現錯誤。

您可以通過多種方式解決這個問題:

  1. 傳遞一個float5.6f
  2. 明確投你floatdoublestatic_cast<float>(5.6)
  3. 提供一個構造函數一個double
  4. 提供一個operator >,需要一個double
  5. 提供採用模板類型的構造函數。
  6. 提供一個operator >採用一個模板類型。
1

operator>需要Distance爲右手操作,所以如果你傳遞一個double,需要轉換。

的問題是,你有兩個constructos

Distance(const float); 
Distance(const int = 0, const int = 0); 

和的5.6類型是double。兩個構造是候選者(因爲它們可以與1個參數調用)和既不需要轉換(double -> floatdouble -> int)的比其它更好。因此錯誤說這個調用是不明確的。

0

您的構造函數允許從float(通過第一個)或int(通過第二個,默認的第二個參數)進行轉換。您正嘗試轉換5.6,這是一個double,其中任一構造函數都是同等匹配的;因此錯誤。

一種選擇是僅使用floatint來初始化它;將5.6更改爲5.6f

另一種選擇是從第二個構造刪除默認參數,因此它不能被用於轉化。如果你想要一個默認構造函數,可以添加一個,或者向轉換構造函數添加一個默認參數。

其他選項是添加更多的過載轉換或比較double。然而,這開始變得相當混亂。

0

編譯器困惑,因爲它無法完成,你問它明確做什麼,即不存在

bool operator >(const double);

但它算出它可以轉換DDistance通過您所提供的構造函數隱式,然後用你的bool operator >(const Distance)。但有兩種方法可以做到這一點double -> int -> Distancedouble -> float -> Distance。雖然,它不能說出哪種方式更合適,因此也是錯誤。

您可以提供重載運算符雙:bool operator >(const double); 或顯式構造雙類型Distance(double)

我會建議編寫一個適當的比較運算符,因爲在構造函數中會有一個隱式轉換和一個創建的臨時對象(儘管在簡單情況下它可能會被編譯器優化)。

同時請注意兩兩件事:

  1. 你應該申報操作的操作數作爲參考(其爲常量反正)即bool operator >(const Distance&);。它避免了創建對象的隱式副本。在當前狀態下,由於copy-by-value參數傳遞,編譯器需要調用複製構造函數來獲得臨時rhs操作數對象。

  2. 看看如果您沒有提供float轉換構造函數會發生什麼。編譯器不會消除歧義。但它不會很好。它會將double分解爲int,然後轉換爲Distance,失去很多精度。聲明這樣的構造函數時使用explicit關鍵字是明智的。所以我建議將其聲明爲explicit Distance(const int = 0, const int = 0);,以避免意外的錯誤。他們可能很討厭追蹤。編譯器可以很容易地創建奇怪的轉換鏈,如果允許的話,這並不總是可取的。

相關問題