第十九篇:复制控制( 下 ) --- 自定义析构函数

Posted 穆晨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十九篇:复制控制( 下 ) --- 自定义析构函数相关的知识,希望对你有一定的参考价值。

前言

       经过前两篇随笔( 上  中 )的分析我们已经解决了具有指针成员的同类对象“ 干涉 ”问题。可惜,前面给出的解决方案代码还是不完整。还有什么问题呢?观察发现,构造函数里面有new的关键字出现,也就是说开辟了新的内存空间,我们也知道new必须也只能对应一个delete,而不应该让系统自己处理( 还不熟练new和delete用法的点这里 ),但这里和new对应的delete去哪里了?

解决思路

       应该何时delete?显然,应该在对象销毁的时候delete。C++中定义了这样一种函数 --- 析构函数,它与构造函数相对应,能在对象被销毁时自动执行。

对【复制控制( 中 )解决方案】的改进

       下面的代码对【复制控制( 中 )解决方案】进行了进一步的改进 --- 设置了自定义的析构函数。至此,复制控制已经完全实现,我们可以正确效率地实现对象( 不论有无指针成员 )间的复制功能了:

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <fstream>
 4 #include <string>
 5 
 6 using namespace std;
 7 
 8 class A {
 9 public:
10     // 构造函数为指针成员开辟空间并赋初值0
11     A() {
12         num_p = new int;
13         *num_p = 0;
14     }
15     // 自定义复制函数 
16     A(const A & a) {
17         num_p = new int;
18         *num_p = a.getNum();
19     }
20     // 自定义赋值运算符号
21     A & operator=(const A & a) {
22         num_p = new int;
23         *num_p = a.getNum();
24     }
25     // 自定义析构函数
26     ~A() {
27         delete num_p;
28     cout << "对象正常销毁" << endl;
29     }
30     // 给指针所指对象赋值
31     void setNum(int num) {
32         *num_p = num;
33     }    
34     // 获取指针所指对象
35     int getNum() const {
36         int num = *num_p;
37         return num;
38     }
39 private:
40     int *num_p;
41 };
42 
43 int main()
44 {
45     A a1, a3;
46 
47     // 设置a1指针成员所指对象的值
48     a1.setNum(1);
49     // 调用自定义的复制函数
50     A a2=a1;
51     // 启用自定义的赋值运算符
52     a3 = a1;
53     // 观察得出a1,a2, a3的指针成员所指对象均为整数1。
54     cout << "a1`s num: " << a1.getNum() << endl;
55     cout << "a2`s num: " << a2.getNum() << endl;
56     cout << "a3`s num: " << a3.getNum() << endl;
57 
58     // 修改a1指针成员所指对象的值
59     a1.setNum(2);
60     // 观察得出a1的指针成员所指对象改了,a2, a3的没变。 
61     cout << "a1`s num: " << a1.getNum() << endl; 
62     cout << "a2`s num: " << a2.getNum() << endl;
63     cout << "a3`s num: " << a3.getNum() << endl;
64 
65     return 0;
66 }

       运行结果:

       

       观察发现每个对象都使用了自定义的析构函数。

说明

       一个有用的经验法则:如果类需要析构函数,它同时也需要自定义复制函数,重载赋值运算符。( 这就是C++中著名的“ 三法则 ” )

以上是关于第十九篇:复制控制( 下 ) --- 自定义析构函数的主要内容,如果未能解决你的问题,请参考以下文章

第十九篇Flowable中的动态表单

python学习[第十九篇] 模块

我的第十九篇博客---JavaScript基本操作

java基础第十九篇之Xml

C++进阶第十九篇——红黑树(概念+代码实现)

Linux从青铜到王者第十九篇:Linux网络基础第二篇之滑动窗口流量控制拥塞控制延迟应答捎带应答