2015-02-11 147 views
0

向下滾動查看TL:DR。作爲成員函數重載*乘法運算符兩次?

這個問題類似於this之一,但有一些差異。它涉及將*運算符兩次加載到名爲jVector的類中,該類僅表示二維笛卡爾向量。

第一種乘法運算是jVector * jVectordot product。第二種類型乘以一個實數,double * jVector。這只是返回一個矢量,其條目乘以double。

下面是一些代碼來說明我想要做的事:

class jVector{ 
    public: 
     double x, y; 

     jVector(double x_val = 0., double y_val = 0.){ 
      x = x_val; 
      y = y_val; 
     } 

     //Operator overload functions 
     //[...] 

     //F1: Dot product (WORKS) 
     double operator* (jVector& factor){ 
      double result; 
      result = x * factor.x; 
      result += y * factor.y; 
      return result; 
     } 

     //F2: Real number multiplication (DOES NOT WORK) 
     jVector operator* (double f){ 
      jVector result; 
      result.x = x * f; 
      result.y = y * f; 
      return result; 
     } 

     //[...] 
} 

//F3: As a non-member (WORKS) 
jVector operator* (double f, jVector V){ 
    jVector result; 
    result.x = V.x * f; 
    result.y = V.y * f; 
    return result; 
} 

三個相關功能標F1F2F3。功能F2F3從不定義在同一時間(我註釋掉其中一個來測試另一個)。

下面是試圖表達類似2.0 * Foo的結果,其中FoojVector類型的向量。當使用F3時,該操作按預期工作,該功能在班級以外定義。但是,如果僅使用F2(成員函數),則會出現一條說明no match for 'operator*' in '2 * Foo'的錯誤。

如果您完全不超載運算符,則會得到相同類型的錯誤,這表明我沒有正確定義F2,或者F2F1衝突。

我相當肯定我的問題是從一個在question I mentioned前面不同,因爲F1F2有不同的返回類型參數類型。

TL:DR

因此,這裏是我的問題:爲什麼我能超載*兩次,只是只要其中一人被定義爲非成員函數?爲什麼兩個重載函數都不能成爲這個類的成員?

+3

'F2'定義了'jVector * double',而不是'double * jVector'。 C++並不認爲這兩個操作具有相同的含義。 – 2015-02-11 23:56:11

回答

2

,因爲你的F2替代需要一個jVector作爲第一個操作數總是它沒有作爲一個成員函數的工作(這是一個成員函數,所以你不必選擇第一個參數是什麼 - 它是jVector *this [被語言隱藏])。編譯器理論上可以允許兩個操作數交換位置(它可以爲x * 2.0轉換爲2.0 * x進行常規數學運算,但由於運算符重載不會被「交換」,所以如果編譯器不會很好DID重新排列它們)

對於第一個操作數是double,您需要一個獨立功能。

2

對於成員函數操作符重載,第一個操作數必須是該類的一個對象。重載函數的參數是第二個操作數。所以:

double operator* (double f){ 

只適用於你在哪裏做a_vector * a_double的情況下,而不是a_double * a_vector

由於這個原因(和其他人),對於重載操作符使用非成員函數通常會更好。我建議做它的方式是:

// member function 
jVector & jVector::operator*=(double f) 
{ 
    x *= f; 
    y *= f; 
    return *this; 
} 

// free functions 
jVector operator* (double f, jVector V) { return V *= f; } 
jVector operator* (jVector V, double f) { return V *= f; }