-
Notifications
You must be signed in to change notification settings - Fork 0
/
OperatorOverloading2_Assign.cpp
126 lines (108 loc) · 2.81 KB
/
OperatorOverloading2_Assign.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// 重载赋值运算符 "="
#include <iostream>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;
class CString
{
private:
char* str;
public:
CString() :str(NULL) {}
CString(const char* s);
CString(const CString& s);
const char* c_str() const;
CString& operator=(const char* s);
CString& operator=(const CString& s);
~CString();
};
CString::CString(const char* s) // 类型转换构造函数,使得 CString s2 = "hello!"; 能够成立
{
/* 这是为了应对这样的情况:CString s = "hello!"; s = "Shenzhou 8!"; 这时便需要释放先前分配的动态内存。
但是因为"="已经有被重载 CString& operator=(const char* s); ,这样的情况并不会触发这个类型转换构造函数,所以可以注释掉这里。
*/
if (s)
{
str = new char[strlen(s) + 1];
strcpy(str, s);
}
else
str = NULL;
}
CString::CString(const CString& s) // 深拷贝
{
if (s.str)
{
str = new char[strlen(s.str) + 1];
strcpy(str, s.str);
}
else
str = NULL;
}
const char* CString::c_str() const
{
return str;
}
CString& CString::operator=(const char* s) // 重载 "=",使得 obj="Good Luck," 能够成立
{
char* str_tmp = NULL;
if (s)
{
str_tmp = new char[strlen(s) + 1];
strcpy(str_tmp, s);
}
else
str_tmp = NULL;
if (str)
delete[] str;
str = str_tmp;
return *this;
}
CString& CString::operator=(const CString& s) // 深拷贝
{
if (this == &s) // 为了应对 s=s 这样的情况。其实这里的自赋值判断是多余的,因为下面的写法可以处理自赋值的情况,同时还是异常安全的。
return *this;
char* str_tmp = NULL;
if (s.str)
{
str_tmp = new char[strlen(s.str) + 1];
strcpy(str_tmp, s.str);
}
else
str_tmp = NULL;
if (str)
delete[] str;
str = str_tmp;
return *this;
}
CString::~CString()
{
if (str)
delete[] str;
}
int main()
{
CString s;
s = "Good Luck,"; // 等价于 s.operator=("Good Luck,");
cout << s.c_str() << endl;
CString s2 = "hello!";
cout << s2.c_str() << endl;
s = "Shenzhou 8!"; // 等价于 s.operator=("Shenzhou 8!");
cout << s.c_str() << endl;
CString& ss = s;
CString& sss = s;
sss = ss; // 第70,71行,s=s 的情况
CString s11, s12;
s11 = "this";
s12 = "that";
s12 = s11; // 深拷贝
CString s21;
s21 = "Transformers";
CString s22(s21); // 深拷贝
return 0;
}
// tips:
// 1. C++规定,"=" 只能重载为成员函数。
// 2. 没有经过重载,"=" 的作用就是把左边的变量变得和右边的相等,即执行逐个字节拷贝的工作,对于指针变量,会使得两个指针指向同一个地方,这样的拷贝就叫做“浅拷贝”。
// 3. 将一个指针变量指向的内容复制到另一个指针变量指向的地方,这样的拷贝就叫做“深拷贝”。
// 4. 第70,71行是为了应付这样的情况:s=s;