赋值运算符重载
对于赋值运算符来说,如果不重载,那么类会自动为我们提供一个赋值运算符。这个默认的赋值运算符跟默认拷贝构造函数一样,就是把一个对象的数据成员的值复制给另一个对象对应的数据成员。但它实现的是一个浅拷贝(logic copy)。数据成员中如果有指针,则编译器默认的赋值运算符不能满足要求,会出现内存泄露。这时我们应重载赋值函数,实现一个深拷贝(physical copy)。
赋值运算符的重载与其他运算符的重载类似,接下来我们就通过一个案例来实现赋值运算符的重载,具体代码如例1所示。
例1
1 #define _CRT_SECURE_NO_WARNINGS
2 #include <iostream>
3 using namespace std;
4 class Internet
5 {
6 public: //为了后面输出方便,成员权限设置成为public
7 char* name;
8 char* url;
9 public:
10 Internet(char* name, char* url); //构造函数
11 Internet(Internet& temp); //拷贝构造函数
12 ~Internet()
13 {
14 delete[]name;
15 delete[]url;
16 }
17 Internet& operator= (Internet& temp); //赋值运算符重载
18 };
19
20 //类Internet成员函数的实现
21 Internet::Internet(char* name, char* url) //构造函数实现
22 {
23 this->name = new char[strlen(name) + 1];
24 this->url = new char[strlen(url) + 1];
25 if (name)
26 strcpy(this->name, name);
27 if (url)
28 strcpy(this->url, url);
29 }
30
31 Internet::Internet(Internet& temp) //拷贝构造函数实现
32 {
33 this->name = new char[strlen(temp.name) + 1];
34 this->url = new char[strlen(temp.url) + 1];
35 if (name)
36 strcpy(this->name, temp.name);
37 if (url)
38 strcpy(this->url, temp.url);
39 }
40
41 Internet& Internet:: operator= (Internet& temp)
42 {
43 delete[]name;
44 delete[]url; //先释放原来空间,再重新申请
45 this->name = new char[strlen(temp.name) + 1];
46 this->url = new char[strlen(temp.url) + 1];
47 if (name)
48 strcpy(this->name, temp.name);
49 if (url)
50 strcpy(this->url, temp.url);
51
52 return *this;
53 }
54
55 int main()
56 {
57 Internet a("传智播客", "http://net.itcast.cn/");
58 cout << "a对象: " << a.name << " " << a.url << endl;
59
60 Internet b(a); //用a对象初始化b,调用的是拷贝构造函数
61 cout << "b对象: " << b.name << " " << b.url << endl;
62
63 Internet c("黑马训练营", "http://www.itheima.com/");
64 cout << "c对象: " << c.name << " " << c.url << endl;
65
66 b = c; //调用赋值重载函数
67 cout << "b对象: " << b.name << " " << b.url << endl;
68 system("pause");
69 return 0;
70 }
运行结果如图1所示。
图1 例1运行结果
在重载赋值运算符时,需要内部先释放name、url指针,因为b对象已经存在,name和url指针所指区域范围大小已经确定,要复制新内容进去,则区域过大或过小都不好,因此需要先释放掉原来指针所指向的内存,根据要复制的内容大小再分配一块内存区域,然后将内容复制进去。
注意:赋值运算符只能重载为类的成员函数。