2012-04-28 17 views
5

比方說,我們有這個A級:如何在不修改操作數的情況下使用一連串的操作符重載?

class A 
{ 
public: 
    int a; 

    A(int b) 
    { 
     a = b; 
    } 
}; 

我想創建一個超載,使得我可以用它像這樣

A a(1),b(2),c(3),&d; 
d = a + b + c; 

,而無需修改每個對象的內容。接下來順理成章的事情將每次分配的內存新小盤這樣的:

A &operator+ (const A &b) 
{ 
    A *c = new A(a+b.a); 
    return *c; 
} 

但是,這將創建一個新的問題:中間結果都將丟失,導致內存泄漏。 我可以很容易地解決這個問題,通過一個靜態函數,需要三個對象引用,並將前兩個的總和存儲在第三個,但我敢打賭,必須有一些方法來使+過載發生我想要的方式。

所以問題是:有沒有什麼辦法可以使用一個操作符重載鏈,它不會修改操作數而不會導致內存泄漏?

回答

9

你可以簡單地通過值使用通和做到這一點:

A operator+ (A other) //pass by value 
{ 
    other.a += a; 
    return other; 
} 

或者,由於成員a是公開訪問,則可以(而應該)使operator+非成員函數:

A operator+(A left, A const &right) 
{ 
    left.a += right.a; 
    return left; 
} 

注意,第一參數按值接受,和第二,參考文獻。這樣,你不需要在函數中聲明一個局部變量。你可以使用第一個參數;畢竟它是本地的函數,你可以做任何你想要做的事情:在這種情況下,我們只需添加right.a並返回它。


類的更好的設計是這樣的:(閱讀評論)

class A 
{ 
    int a; //make it private 
public:  
    A(int b) : a(b) //use member initialization list 
    { 
    } 
    A& operator+=(A const & other) //add `+=` overload, as member of the class 
    { 
     a += other.a; 
     return *this; 
    } 
}; 

//and make `+` non-member and non-friend 
A operator+(A left, A const & right) 
{ 
    left += right; //compute this in terms of `+=` which is a member function 
    return left; 
} 
+1

+1以避免手動複製。 – Sven 2012-04-28 03:19:06

+0

抱歉,您的回答似乎忽略了一個事實,即我特意詢問了一種不修改任何操作數對象 – 2012-04-28 03:21:23

+0

@ user803253的方法:我不修改*操作數*;操作數作爲值傳遞,這意味着您在函數中修改的是操作數的*副本。無論如何,我發佈了一個更好的設計,你應該採用。 – Nawaz 2012-04-28 03:25:39

4

operator+內部沒有必要使用指針。您可以在堆棧分配的中間目標,然後返回它:

A operator+ (const A &b) 
{ 
    A c(a+b.a); 
    return c; 
} 

或者只是:

A operator+ (const A &b) 
{ 
    return A(a+b.a); 
} 

或者更簡單:

​​

由於這個隱式調用A::A(int)

請注意,我從返回類型中刪除了引用。您不能將非const引用返回給本地。

那麼你會使用這種方式:

A a(1),b(2),c(3),d; 
d = a + b + c; 

注意d不再是一個參考。

+0

警示:您正在返回引用臨時對象。這不是一個好主意! – 2012-04-28 03:15:41

+0

很棒!謝謝。我知道一些簡單的事情需要完成。 – 2012-04-28 03:17:19

+0

只要我發佈我的答案,我注意到OP是返回引用,但立即修復我的答案。 – mfontanini 2012-04-28 03:17:45

相關問題