2011-12-26 54 views
2

我需要在類中實現重載的賦值運算符,因此vector.erase函數將按照「vector::erase with pointer member」的答案中的建議正常工作。爲了相同的目的,我也實現了一個拷貝構造函數。通過以下操作符的實現,我得到以下警告:重載的賦值運算符會導致有關遞歸的警告

'Player :: operator =':在所有控制路徑上遞歸,函數將導致運行時堆棧溢出。

顯然Player::operator=的執行不正確。什麼是正確的實施?

//Copy constructor: 
Player::Player(const Player& otherPlayer) { 
    ... 
} 


Player& Player::operator=(const Player& rhs) { 
    *this = Player(rhs); 
    return *this; 
} 

multimap的擦除功能是否與向量一樣工作?當我在multimap中使用時,我沒有收到有關不執行重載operator=的錯誤,因爲它與矢量一樣。真相是什麼?

此外,玩家可以參考銀行作爲會員。我是否應該僅通過=來完成參考的分配?那麼複製構造函數的目的是什麼?

+0

我編輯了我的答案,讓我知道如果沒關係! – Tom 2011-12-26 11:11:10

+0

關於更新:您幾乎從不擁有參考成員。理想情況下,只有其唯一目的是管理單個非託管資源的類應具有用戶定義的析構函數,複製構造函數和複製賦值運算符。 你可以嘗試描述你的實際課堂設計嗎?從中我們可以嘗試推斷出更好的實現。 – Philipp 2011-12-26 11:16:54

+0

這個帖子有太多的問題。 SO使用Q&A格式。不同的問題應該單獨發佈。關於如何在賦值運算符和拷貝構造函數中處理引用成員的問題應該是一個單獨的問題(儘管首先要進行搜索以確保它之前沒有被問到)。 – outis 2011-12-26 11:33:14

回答

7

你的問題是這樣的一行:

*this = Player(rhs); 

這需要重載=再次方法,導致遞歸循環。 你應該分配單獨的所有成員:

x = rhs.x; 
y = rhs.y; // for example 

編輯同時請注意,您傳遞的對象是同一類型的對象的實例方法屬於,你可以訪問私有成員就像你通常會爲公衆成員。

EDIT2據我所知,你不會想複製一個參考,因爲這意味着在同一銀行的對象是從打破封裝兩個對象訪問,可能會造成一些意想不到的問題。是否有任何特定的原因,你不使用指針?如果銀行的對象是一個指針,你可以重載爲銀行=運算符,然後通常分配給它:

bank = rhs.bank; 

至於拷貝構造函數和賦值運算符的差異,一個快速谷歌搜索打開了這個鏈接:http://prashanth-cpp.blogspot.com/2007/01/assignment-operator-vs-copy-constructor.html

1

問題是,您從=內部致電=。取而代之的是,你應該字段分配類域的元素,像這樣:

Player& Player::operator=(const Player& rhs) { 
    name = rhs.name; 
    score = rhs.score; 
    return *this; 
} 
4

的正確實施operator=的一個好方法是copy-and-swap idiom

Player& Player::operator=(Player rhs) { // note: pass by value 
    this->swap(rhs); 
    return *this; 
} 

void Player::swap(Player& other) { // member function 
    using std::swap; 
    swap(this->name, other.name); 
    swap(this->score, other.score); 
} 

void swap(Player& a, Player& b) { // free function 
    a.swap(b); 
} 
0

在回答

那麼複製構造函數的目的是什麼?

目的是讓您最完全地控制複製的功能。例如,如果你的類包含一個char*成員,並且你創建了一個副本,你可能想要保持char *的值與你正在複製的實例的值相同(即指向同一位置的指針),或者你可能想複製它指向的字符串。
編譯器本身並不知道你想要的這些選擇中的哪一個,所以這就是你進來的地方。