在 C++ 中实现赋值运算符重载
本文将介绍几种如何在 C++ 中实现赋值运算符重载的方法。
使用复制赋值运算符在 C++ 中实现重载的赋值运算符
C++ 提供了重载运算符的功能,这是在特定类上调用内置运算符时调用自定义函数的一种常用方法。这些功能应有一个特殊的名称,以 operator
开头,后跟特定的操作符符号本身。例如,可以使用名为 operator=
的函数来实现自定义赋值运算符。赋值运算符通常应返回对其左侧操作数的引用。请注意,如果用户未明确定义副本赋值运算符,则编译器会自动生成一个。当该类不包含在堆内存上手动赋值的任何数据成员时,生成的版本将具有足够的功能。它甚至可以通过将每个元素赋值给相应的对象成员来处理数组成员。但是,在处理动态内存数据成员时,它有缺点,如下面的示例代码所示。
#include <iostream>#include <string>#include <utility>#include <vector>using std::cout; using std::endl;
using std::vector; using std::string;
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::vector; using std::string;
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
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站。本站所有源码与软件均为原作者提供,仅供学习和研究使用。如您对本站的相关版权有任何异议,或者认为侵犯了您的合法权益,请及时通知我们处理。