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

前言

经过前两篇随笔( 上  中 )的分析我们已经解决了具有指针成员的同类对象“ 干涉 ”问题。可惜,前面给出的解决方案代码还是不完整。还有什么问题呢?观察发现,构造函数里面有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++中著名的“ 三法则 ” )

时间: 2024-12-29 07:00:00

第十九篇:复制控制( 下 ) --- 自定义析构函数的相关文章

Python之路【第十九篇】:爬虫

Python之路[第十九篇]:爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引.模拟程序或者蠕虫. Requests Python标准库中提供了:urllib.urllib2.httplib等模块以供Http请求,但是,它的 API 太渣了.它是为另一个时代.另一个互联网所创建的.它需要巨量的工作,甚至包括各种方法覆盖,来完成最简单的任务. import

第十九篇:USB Audio/Video Class设备协议

在Spring 3 中,对表单提交的校验方式比较常见的有两种 (1)基于注解:对于简单的属性校验,例如,长度,非空等,可以使用Spring,或是Hibernate自带的校验注解 (2)自定义校验类:对于复杂的业务校验可以自定义校验类,该类继承自org.springframework.validation.Validator (3)前台JS校验 增加表单校验功能大概分一下几个步骤 定义校验规则 基于注解的验证 只需要在相关的实体字段上添加校验注解即可,下面的例子基于hibernate的校验标签 i

Python开发【第十九篇】:Python操作MySQL

Python开发[第十九篇]:Python操作MySQL 本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同. 下载安装 ? 1 pip3 install pymysql 使用操作 1.执行SQL + ? 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

第十七篇:复制控制( 上 ) --- 自定义复制函数

前言 若要将a对象复制给b对象,编译器应当做何工作?C++初学者也许会直接说” a对象的成员复制给b对象的成员 “.在很多情况下,这种说法正确,事实上C++会给类定义一个默认的复制函数,它所做的工作也正是如此.但,下面问题来了:如果类的成员当中有指针,这种做法还行吗?本文将对这个问题作出实例分析. 一个典型错误示例 下面这个代码示例用来检验前言中所提到的问题: 1 #include <iostream> 2 #include <cstdlib> 3 #include <fst

Python之路【第十九篇】自定义分页实现(模块化)

自定义分页 1.目的&环境准备 目的把分页写成一个模块的方式然后在需要分页的地方直接调用模块就行了. 环境准备Django中生成一个APP并且注册,配置URL&Views 配置URL from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^user_lis

python全栈开发基础【第十九篇】进程

一.什么是进程 进程:正在进行的一个过程或是一个任务.而负责执行任务的是CPU. 举例:(单核+多道,实现多个进程的并发): 比如说你就是一个CPU,你下午有几个活要干,吃饭,洗衣服,上厕所等.但是就在那一下午要把所有的事干完(而CPU同一时间只能干一件事),那么如何才能让多个任务实现并发执行的效果呢?那么,你应该这样做,你可以先做饭,在等待饭熟的过程中你可以去洗个衣服,洗的差不多饭也就熟了,那么你在去上个厕所也可以嘛. 二.进程与程序的区别 程序仅仅只是一堆代码而已,而进程指的是程序的运行过程

第二十九篇:浅谈一线经理的管理策略

今天看到一条朋友圈中的内容:好单位与坏单位 文中列举了好与坏的各种分别: 好公司: 牛人很多,比你更谦卑,更努力,你不努力都不好意思呆下去! 员工都有目标有理想有希望 每个人脸上都写着"价值与目标" 坏公司: 扯皮,推诿,不承担,办事效率低,发牢骚的人很多, 不仅不干活,而且党同伐异,想把干活的人全干掉! 员工以混日子,不承担责任,得过且过去生存. 每个人的脸上都写着"自我与个性" 具体到一个公司,都是好公司与坏公司的结合体. 刚刚起步的STARTUP,大家都是志同

第十八篇 liunx系统下 JDK的安装

大家好,今天我给大家简单介绍一下我所学到的一些经验和总结: 今天我们学习了如何在liunx系统下 安装 JDK ,说到JDK 可能很多人都知道,JDK :英文名叫 Java Development Kit ,意思就是 Java 语言的软件开发工具包:其作用 我就不再一一介绍了,好了,下面就来说一下安装步骤吧: 第一步,先找到安装包,并且在DOS命令下打开,当然 liunx系统下的JDK安装包 跟Windows系统下的 JDK安装包不一样,这点需要大家注意一下: 第二步,配置环境变量,当然也是在

【Python之路】第十九篇--Python操作MySQL

本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同. 下载安装 pip3 install pymysql 使用操作 1.执行SQL # 创建连接 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='db1') # 创建游标