我使用下面的代碼來測驗復制賦值運算子的行為:
#include <iostream>
using namespace std;
int group_number = 10; // Global
class Player {
public:
explicit Player(const int &g): group(g)
{
}
Player& operator=(const Player& rhs)
{
cout << "Copy assignment operator called " << endl;
return *this;
}
void set_stamina(int i) {stamina = i; }
int get_stamina() {return stamina; }
const int &get_group() const { return group; }
protected:
const int &group;
private:
int stamina;
}; // End of Player class
class Round {
public:
Round(const Player &p)
{
main_player = &p;
}
const Player &get_main_player() const
{
return *main_player;
}
protected:
const Player *main_player;
}; // End of Round class
// Test code
int main()
{
Player p1(group_number);
Round r(p1);
p1.set_stamina(100);
// Add player2 in the same group as p1
Player p2(group_number);
p2 = r.get_main_player();
cout << "This is p1's stamina: " << p1.get_stamina()
<< ", and p1's group number: " << p1.get_group() << endl;;
cout << "This is p2's stamina: " << p2.get_stamina()
<< ", and p2's group number: " << p2.get_group() << endl;;
return 0;
}
我預計 p1 和 p2 的值相同stamina。但輸出顯示 p2stamina與 p1 不同
Copy assignment operator called
This is p1's stamina: 100, and p1's group number: 10
This is p2's stamina: 241098768, and p2's group number: 10
為什么復制賦值運算子不將 p1 的值復制stamina到 p2?
uj5u.com熱心網友回復:
您尚未在復制賦值運算子中復制資料成員。stamina因此,只需stamina = rhs.stamina;在復制賦值運算子中添加即可,您將獲得預期的輸出。所以修改后的定義operator=如下:
Player& operator=(const Player& rhs)
{
cout << "Copy assignment operator called " << endl;
stamina = rhs.stamina; //ADDED THIS
return *this;
}
另外,請注意,在您的原始代碼片段中,由于資料成員stamina未初始化,因此它具有不確定的值。使用這個未初始化的變數(您在撰寫時所做p2.get_stamina();的)是未定義的行為。
未定義的行為意味著任何事情1都可能發生,包括但不限于給出預期輸出的程式。但永遠不要依賴(或基于)具有未定義行為的程式的輸出。
因此,您看到的輸出是未定義行為的結果。正如我所說,不要依賴具有 UB 的程式的輸出。
因此,使程式正確的第一步是洗掉 UB。只有這樣,您才能開始推理程式的輸出。
要解決這個更嚴重的問題,只需對資料成員使用類內初始化stamina程式。
class Player {
//other members here
private:
int stamina = 0; //USE IN-CLASS INITIALIZER
};
1有關未定義行為的更技術上準確的定義,請參見此處提到:對程式的行為沒有限制。
uj5u.com熱心網友回復:
為什么復制賦值運算子不將 p1 的耐力值復制到 p2?
您定義了運算子。您不會在運算子的定義中復制任何值,因此不會復制任何值。
您可以像這樣分配成員:
stamina = rhs.stamina;
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/416012.html
標籤:
上一篇:禁用非默認選中專案的復選框
下一篇:使用帶輸入的類連接實體屬性
