在 C++ 中實現賦值運算子過載

本文將介紹幾種如何在 C++ 中實現賦值運算子過載的方法。
使用複製賦值運算子在 C++ 中實現過載的賦值運算子
C++ 提供了過載運算子的功能,這是在特定類上呼叫內建運算子時呼叫自定義函式的一種常用方法。這些功能應有一個特殊的名稱,以 operator
開頭,後跟特定的操作符符號本身。例如,可以使用名為 operator=
的函式來實現自定義賦值運算子。賦值運算子通常應返回對其左側運算元的引用。請注意,如果使用者未明確定義副本賦值運算子,則編譯器會自動生成一個。當該類不包含在堆記憶體上手動賦值的任何資料成員時,生成的版本將具有足夠的功能。它甚至可以通過將每個元素賦值給相應的物件成員來處理陣列成員。但是,在處理動態記憶體資料成員時,它有缺點,如下面的示例程式碼所示。
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::vector;
class Person {
public:
Person() {
name = new string;
surname = new string;
};
Person(string n, string s) {
name = new string(std::move(n));
surname = new string(std::move(s));
}
Person(Person &p) {
name = new string(*p.name);
surname = new string(*p.surname);
}
~Person() {
delete name;
delete surname;
}
void renamePerson(const string &n, const string &s) {
name->assign(n);
surname->assign(s);
};
void printPerson() { cout << *name << " " << *surname; }
private:
string *name;
string *surname;
};
int main() {
Person P1("Buddy", "Rich");
Person P2 = P1;
P1.printPerson();
cout << endl;
P2.printPerson();
cout << endl;
P1.renamePerson("Jay", "Roach");
P1.printPerson();
cout << endl;
P2.printPerson();
cout << endl;
Person P3;
P3 = P1;
P1.printPerson();
cout << endl;
P3.printPerson();
cout << endl;
P1.renamePerson("Liam", "White");
P1.printPerson();
cout << endl;
P3.printPerson();
cout << endl;
exit(EXIT_SUCCESS);
}
輸出:
Buddy Rich
Buddy Rich
Jay Roach
Buddy Rich
Jay Roach
Jay Roach
Liam White
Liam White
上面的程式碼僅明確定義了複製構造器,當將 P1
物件的內容賦值給 P3
物件時,會導致不正確的行為。請注意,第二次呼叫 P1.renamePerson
函式的第二次呼叫不應該修改 P3
物件的資料成員,但它修改了。解決方案是定義一個過載的賦值運算子,即複製賦值運算子。下一個程式碼片段實現了 Person
類的版本,該版本可以正確地複製賦值同一類的兩個物件。但是請注意,複製賦值功能中的 if
語句可確保即使將物件賦值給自身,操作符也可以正常工作。
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::vector;
class Person {
public:
Person() {
name = new string;
surname = new string;
};
Person(string n, string s) {
name = new string(std::move(n));
surname = new string(std::move(s));
}
Person(Person &p) {
name = new string(*p.name);
surname = new string(*p.surname);
}
~Person() {
delete name;
delete surname;
}
Person &operator=(const Person &p) {
if (this != &p) {
*name = *(p.name);
*surname = *(p.surname);
}
return *this;
}
void renamePerson(const string &n, const string &s) {
name->assign(n);
surname->assign(s);
};
void printPerson() { cout << *name << " " << *surname; }
private:
string *name;
string *surname;
};
int main() {
Person P1("Buddy", "Rich");
Person P2 = P1;
P1.printPerson();
cout << endl;
P2.printPerson();
cout << endl;
P1.renamePerson("Jay", "Roach");
P1.printPerson();
cout << endl;
P2.printPerson();
cout << endl;
Person P3;
P3 = P1;
P1.printPerson();
cout << endl;
P3.printPerson();
cout << endl;
P1.renamePerson("Liam", "White");
P1.printPerson();
cout << endl;
P3.printPerson();
cout << endl;
exit(EXIT_SUCCESS);
}
輸出:
Buddy Rich
Buddy Rich
Jay Roach
Buddy Rich
Jay Roach
Jay Roach
Liam White
Jay Roach
Enjoying our tutorials? Subscribe to DelftStack on YouTube to support us in creating more high-quality video guides. Subscribe
作者: Jinku Hu