2014-03-05 25 views
0

我有一個關於運算符重載的問題。以下是我的示例代碼。如果你可以通讀它並且我的問題在下面。爲什麼我的操作符重載處理左對象與右對象?

//class definition 
class example 
{ 
private: 
    int a ; // Defined in FeetInches.cpp 
public: 
    void seta(int f) 
    { 
     a = f; 
    } 
    example operator + (const example &); // Overloaded + 

    int geta() 
    { 
     return a; 
    } 
}; 

example example::operator + (const example &right) 
{ 
    example temp; 

    temp.a = a + right.a; 
    return temp; 
} 

//主

#include "header" //this is the class definition above 
#include <iostream> 
using namespace std; 

int main() 
{ 
    example r; 
    r.seta(1); 

    example s; 
    s.seta(1); 

    example t; 
    t = r + s; 
    t = r + 1; //if included it won't compile 
    t = 1 + r; //if included it won't compile 

    int x = t.geta(); 
    cout << x; 

    cin.get(); 
    return 0; 
} 

我瞭解,當您嘗試添加到一起使用操作符重載,他們應該是相同的對象。

下面是問題: 我最近看到什麼時候該對象是在它編譯的操作符的一側,但是當它在另一側時它沒有。如:

t = r + 1;它編譯。 t = 1 + r;它沒有。

(另外我知道在我的例子這是行不通的任何一種方式,但只是更容易與框架代碼的問題。)

如何操作符重載時的對象是對操作的一面,但不能編譯當它在另一個上時編譯。

感謝

+5

嘗試使用'運營商+'重寫你的任務:'r.operator +(1)' 。嘗試換一種方式,你會從編譯器的角度看到。 –

+0

這就是爲什麼他們經常推薦將'operator + ='實現爲成員函數,然後將'operator +'實現爲全局函數。這樣隱式轉換可以發生在'+'運算符的左側或右側。 – Graznarak

回答

-1

t = r + 1;裝置t = r.operator+(1);如果r限定了匹配operator+()方法,否則它意味着t = operator+(r, 1);代替。它不會編譯,因爲你沒有定義任何+操作是發生在左側有一個example和右側,比如一個int

// as a class method: 

class example 
{ 
    ... 
public: 
    ... 
    example operator + (int right) const; 
}; 

example example::operator + (int right) const 
{ 
    example temp; 
    temp.seta(a + right); 
    return temp; 
} 

或者:

// as a global operator: 

class example 
{ 
    ... 
public: 
    ... 
    friend example operator + (const example& left, int right); 
}; 

example operator + (const example& left, int right) 
{ 
    example temp; 
    temp.seta(left.a + right); 
    return temp; 
} 

如果您已經定義的構造器其採用int作爲輸入,編譯器會創建一個臨時example當你傳遞一個int價值的example::operator+(const example&)方法,如:

class example 
{ 
    ... 
public: 
    example (int f); 
    ... 
    example operator + (const example& right); 
}; 

example::example::(int f) 
    : a(f) 
{ 
} 

example example::operator + (const example& right) 
{ 
    example temp; 
    temp.a = a + right.a; 
    return temp; 
} 

同樣,t = 1 + r;表示t = operator+(1, r);(因爲1不是類類型)。它不會編譯,因爲你沒有定義一個全局+操作是發生在左側有一個int,右側的example

class example 
{ 
    ... 
public: 
    ... 
    friend example operator + (int left, const example& right); 
}; 

example operator + (int left, const example& right) 
{ 
    example temp; 
    temp.a = left + right.a; 
    return temp; 
} 
+0

爲什麼這會降低投票率? –

0

如果重寫有問題的語句冗長,它看起來像:

t.operator=(1.operator+(r)); 

不使一個很大的意義和混淆編譯器。

令人困惑的是,它可以將數字1轉換爲example的實例或將變量r轉換爲整數。不幸的是,你在課堂上沒有提供足夠的信息去做。

如果你爲你的類的構造函數,它接受一個整數,事情可能出來減少混亂:

class example 
{ 
    public: 
    example(int new_value) : a(new_value) 
     { ; } 
}; 

現在您所提供的編譯器的方法轉換成整數example秒。

另一個替代方案是提供這樣一種鑄造或轉換操作符:

class example 
{ 
    public: 
    int operator int (const example& e) 
    { 
     return e.a; 
    } 
}; 

還有其它替代方案,例如,創建的加成方法,它有一個整數。

編輯1:
如果你在設計一個單位類提防常量。你不知道常數是在什麼單位,如英尺或英寸。編譯器將無法提供幫助,因爲數字常量沒有與它們關聯的單位。

+1

編譯器將't = 1 + r;'視爲't.operator =(operator +(1,r));',因爲'1'不是可以有自己的'operator +()'方法的對象類型定義。您關注的是對象一元運算符,但不要忘記也存在全局二元運算符。 –

+0

@RemyLebeau:謝謝你提供的信息。 –

0

這真的很簡單,當你超載運營商,你可以做到這一點有兩種方式:

首先是喜歡你這樣做。你在其中插入了重載的操作符。這樣左邊的論點必須是這個類的對象。爲什麼?因爲當你調用這個操作符時,你可以將它作爲你班級中每個函數的調用。你不能以其他方式做,因爲你不能通過其他類型調用這個函數。

其次,你讓重載的操作符成爲你的班級的朋友。如果你想添加的整數或其它類型的,你必須只修改您的運營商加入

example& operator + (const example &left, const example &right){...} 

所以: 在你的類,你把這個行:

friend example& operator + (const example &left, const example &right); 

而且你的類定義後,你把這個它是這樣的:

example& operator + (const example &left, const int right){...} 

或本:

example& operator + (const int left, const example &right){...} 

如果要從操作者的左側或右側添加int,請選擇其中一個或兩個。

相關問題