-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathC++拷贝赋值符号、构造函数、析构函数
270 lines (208 loc) · 6.55 KB
/
C++拷贝赋值符号、构造函数、析构函数
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
#include<iostream>
#include<vector>
using namespace std;
struct X
{
X() { cout << "构造函数()" << endl; }
X(const X&) { cout << "拷贝构造函数()" << endl; }
X& operator=(const X &rhs) { cout << "拷贝赋值函数符=(const X&)" << endl; return *this; }
~X() { cout << "析构函数()" << endl; }
};
void f1(X x)
{
}
void f2(X &x)
{
}
int main()
{
cout << "局部变量:" << endl;
X x;
cout << endl;
cout << "非引用参数传参:" << endl;
f1(x);
cout << endl;
cout << "引用参数传参:" << endl;
f2(x);
cout << endl;
cout << "动态分配:" << endl;
X *px = new X;
cout << endl;
cout << "添加到容器中:" << endl;
vector<X> vx;
vx.push_back(x);
cout << endl;
cout << "释放动态分配对象:" << endl;
delete px;
cout << endl;
cout << "间接初始化和赋值:" << endl;
X y = x;
y = x;
cout << endl;
cout << "程序结束:" << endl;
return 0;
}
程序结果:
局部变量:
构造函数()
非引用参数传参:
拷贝构造函数()
析构函数()
引用参数传参:
动态分配:
构造函数()
添加到容器中:
拷贝构造函数()
释放动态分配对象:
析构函数()
间接初始化和赋值:
拷贝构造函数()
拷贝赋值函数符=(const X&)
程序结束:
析构函数()
析构函数()
析构函数()
请按任意键继续. . .
如果一个类需要自定义析构函数,几乎可以肯定它也需要自定义拷贝赋值运算符和拷贝构造函数。
如果一个类需要一个拷贝构造函数,几乎可以肯定它也需要一个拷贝赋值运算符,反之亦然。但是这并不意味着一定需要析构函数。
default关键字表示使用默认的函数,阻止拷贝可以用delete关键字,但是析构函数不能是删除的成员。在新的标准发布之前,类是通过将拷贝构造函数和拷贝赋值运算符声明为private的来阻止拷贝的,但是应该使用delete。
拷贝控制和资源管理
通常,管理类外资源必须定义拷贝控制成员。这又分为两种1、行为像值的类 2、行为像指针的类
在第一种中要注意的是拷贝赋值运算符函数,这里包括了拷贝赋值函数和析构函数的功能。
在第二种中我们希望直接管理资源时,我们可以使用引用计数。(同一个值的关联数)
#include<iostream>
#include<string>
using namespace std;
class Complex
{
private:
double m_real;
double m_imag;
public:
// 无参数构造函数
// 如果创建一个类你没有写任何构造函数,则系统会自动生成默认的无参构造函数,函数为空,什么都不做
// 只要你写了一个下面的某一种构造函数,系统就不会再自动生成这样一个默认的构造函数,如果希望有一个这样的无参构造函数,则需要自己显示地写出来
Complex(void)
{
m_real = 0.0;
m_imag = 0.0;
cout << "默认构造函数" << endl;
}
// 一般构造函数(也称重载构造函数)
// 一般构造函数可以有各种参数形式,一个类可以有多个一般构造函数,前提是参数的个数或者类型不同(基于c++的重载函数原理)
// 例如:你还可以写一个 Complex( int num)的构造函数出来
// 创建对象时根据传入的参数不同调用不同的构造函数
Complex(double real, double imag)
{
m_real = real;
m_imag = imag;
}
// 复制构造函数(也称为拷贝构造函数)
// 复制构造函数参数为类对象本身的引用,用于根据一个已存在的对象复制出一个新的该类的对象,一般在函数中会将已存在对象的数据成员的值复制一份到新创建的对象中
// 若没有显示的写复制构造函数,则系统会默认创建一个复制构造函数,但当类中有指针成员时,由系统默认创建该复制构造函数会存在风险,具体原因请查询有关 “浅拷贝” 、“深拷贝”的文章论述
Complex(const Complex & c)
{
// 将对象c中的数据成员值复制过来
m_real = c.m_real;
m_imag = c.m_imag;
cout << "拷贝构造函数" << endl;
}
// 类型转换构造函数,根据一个指定的类型的对象创建一个本类的对象
// 例如:下面将根据一个double类型的对象创建了一个Complex对象
Complex::Complex(double r)
{
m_real = r;
m_imag = 0.0;
}
// 等号运算符重载
// 注意,这个类似复制构造函数,将=右边的本类对象的值复制给等号左边的对象,它不属于构造函数,等号左右两边的对象必须已经被创建
// 若没有显示的写=运算符重载,则系统也会创建一个默认的=运算符重载,只做一些基本的拷贝工作
Complex &operator=(const Complex &rhs)
{
// 首先检测等号右边的是否就是左边的对象本,若是本对象本身,则直接返回
if (this == &rhs)
{
return *this;
}
// 复制等号右边的成员到左边的对象中
this->m_real = rhs.m_real;
this->m_imag = rhs.m_imag;
cout << "拷贝赋值运算符函数" << endl;
// 把等号左边的对象再次传出
// 目的是为了支持连等 eg: a=b=c 系统首先运行 b=c
// 然后运行 a= ( b=c的返回值,这里应该是复制c值后的b对象)
return *this;
}
//析构函数
~Complex()
{
cout << "析构函数" << endl;
}
};
Complex test1(const Complex& c)
{
return c;
}
Complex test2(const Complex c)
{
return c;
}
Complex test3()
{
static Complex c(1.0, 5.0);
return c;
}
Complex& test4()
{
static Complex c(1.0, 5.0);
return c;
}
void main()
{
Complex a, b;
// 下面函数执行过程中各会调用几次构造函数,调用的是什么构造函数?
cout << "====================" << endl;
test1(a);
cout << "=====================" << endl;
test2(a);
cout << "======================" << endl;
b = test3();
cout << "=======================" << endl;
b = test4();
cout << "========================" << endl;
test2(1.2);
cout << "=========================" << endl;
// 下面这条语句会出错吗?
test1(1.2);
//test1( Complex(1.2 )) 呢?
}
程旭结果如下:
默认构造函数
默认构造函数
====================
拷贝构造函数
析构函数
=====================
拷贝构造函数
拷贝构造函数
析构函数
析构函数
======================
拷贝构造函数
拷贝赋值运算符函数
析构函数
=======================
拷贝赋值运算符函数
========================
拷贝构造函数
析构函数
析构函数
=========================
拷贝构造函数
析构函数
析构函数
析构函数
析构函数
析构函数
析构函数
请按任意键继续. . .