C++赋值运算符重载
赋值运算符重载和拷贝构造函数的作用类似,都是将类对象进行复制。
需要注意的点也是一样,就是堆区重复释放问题
这个问题的诱因就是,编译器默认的拷贝是浅拷贝,而浅拷贝会出现重复释放内存的现象。
具体可以参考 C++深拷贝与浅拷贝
赋值运算符重载的目的就是复制类,而每个类的内容不尽相同
所以,赋值运算符重载应该定义在类内部
- 赋值运算符重载(浅拷贝)
编译器提供的代码是浅拷贝。
此时不能自己定义析构函数,否则会带来堆区重复释放的问题。
#include <iostream>
using namespace std;
#include <string>
class Person
{
public:
Person(int age)
{
//将年龄数据开辟到堆区
m_Age = new int(age);
}
//重载赋值运算符
//安利一个tip
//在不知道返回值类型的时候可以用void代替,
//等到定义完毕后再修改返回值类型即可
void operator=(Person &p)
{
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
//编译器提供的代码是浅拷贝
m_Age = p.m_Age;
}
//此时不能自己定义析构函数,否则会带来堆区重复释放的问题
//~Person()
//{
// if (m_Age != NULL)
// {
// delete m_Age;
// m_Age = NULL;
// }
//}
//年龄的指针
int *m_Age;
};
void test01()
{
Person p1(18);
Person p2(20);
Person p3(30);
p2 = p1; //赋值操作
cout << "p1的年龄为:" << *p1.m_Age << endl;
cout << "p2的年龄为:" << *p2.m_Age << endl;
cout << "p3的年龄为:" << *p3.m_Age << endl;
}
int main() {
test01();
system("pause");
return 0;
}
- 赋值运算符重载(深拷贝)
提供深拷贝 解决浅拷贝堆区重复释放的问题
#include <iostream>
using namespace std;
#include <string>
class Person
{
public:
Person(int age)
{
//将年龄数据开辟到堆区
m_Age = new int(age);
}
//重载赋值运算符
void operator=(Person &p)
{
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
编译器提供的代码是浅拷贝
//m_Age = p.m_Age;
//提供深拷贝 解决浅拷贝的问题
m_Age = new int(*p.m_Age);
}
~Person()
{
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
}
//年龄的指针
int *m_Age;
};
void test01()
{
Person p1(18);
Person p2(20);
Person p3(30);
p2 = p1; //赋值操作
cout << "p1的年龄为:" << *p1.m_Age << endl;
cout << "p2的年龄为:" << *p2.m_Age << endl;
cout << "p3的年龄为:" << *p3.m_Age << endl;
}
int main() {
test01();
system("pause");
return 0;
}
- 解决连续赋值问题
曾记否,我们原来的赋值运算有这样连续赋值的形式
int a = 10;
int b = 20;
int c = 30;
c = b = a;
- 大家可以用上面的程序试一试
结果可想而知,必然是跑不通的。
如何解决呢? - 由于我们一开始定义的是void返回值,都知道void是无法再次赋值的!
那么就应该将返回值类型修改为Person类
等等,你确定是Person类?不是Person&? - 好吧,应该是Person&,为什么呐?
因为如果是Person类,返回的将是一个局部变量,而局部变量在函数运行结束之后就销毁了!
这是正确的代码
#include <iostream>
using namespace std;
#include <string>
class Person
{
public:
Person(int age)
{
//将年龄数据开辟到堆区
m_Age = new int(age);
}
//重载赋值运算符
Person& operator=(Person &p)
{
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
编译器提供的代码是浅拷贝
//m_Age = p.m_Age;
//提供深拷贝 解决浅拷贝的问题
m_Age = new int(*p.m_Age);
//返回自身
return *this;
}
~Person()
{
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
}
//年龄的指针
int *m_Age;
};
void test01()
{
Person p1(18);
Person p2(20);
Person p3(30);
p3 = p2 = p1; //赋值操作
cout << "p1的年龄为:" << *p1.m_Age << endl;
cout << "p2的年龄为:" << *p2.m_Age << endl;
cout << "p3的年龄为:" << *p3.m_Age << endl;
}
int main() {
test01();
system("pause");
return 0;
}