C++学习记录-面向对象-运算符重载4-赋值运算符重载

一、重载的原因

一般情况下,编译系统会为每个类提供一个默认的赋值运算符,用这个默认的赋值运算符操作类对象时,该运算符会把这个类的所有数据成员都进行一次赋值操作。

但是,当遇到以下情况时程序会报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class level {
public:
int *lv;
//创建一个int型指针属性

public:
level(int a) { lv=new int(a); }
//构造函数,在堆区开辟一块内存并使指针指向它


~level()
{
if (lv != NULL)
{
delete lv;
lv = NULL;
}
}//析构函数,释放内存
};
1
2
3
4
5
6
7
8
void test()
{
level l1(20);
level l2(18);
l2= l1;//默认赋值
}

test();//调用

程序报错:已引发异常

因为在test函数调用完成后,要释放l1,l2两个对象,但此时l1,l2中的指针指向的都是同一块内存空间(l2=l1),造成了同一块内存被重复释放

为解决这个问题,要用到重载赋值运算符

二、重载赋值运算符及其注意事项

  • 重载赋值运算符必须写为成员函数

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class level {
public:
int *lv;
public:
level(int a) { lv=new int(a); }//构造函数
~level()
{
if (lv != NULL)
{
delete lv;
lv = NULL;
}
}//析构函数


void operator=(level& a)
{
lv = new int(*(a.lv));
}//重载赋值运算符

};

重载赋值运算符,让被赋值的对象的指针指向一块新开辟的内存,避免了内存被重复释放

若要实现连等,则将返回值类型写为 对象的引用,如下:

1
2
3
4
5
6
7
level& operator=(level& a)
{
lv = new int(*(a.lv));

return *this;

}//返回引用,实现连等