C++ 构造过程和析构过程
1、C++构造和析构的过程,类似于穿衣脱衣的过程。穿衣是:先穿内衣,再穿外套。脱衣是:先脱外套,再脱内衣。C++构造过程:首先调用父类构造方法,再调用子类构造方法。C++析构过程:首先调用子类析构方法,再调用父类析构方法。
2、子类不能继承父类的构造方法和析构方法,除此之外,其他的成员都能继承,包括父类的private成员,只不过子类不能访问private成员。
3、思考一下,为什么子类不能继承父类的构造方法?
想一想,构造方法是干什么的?构造方法是初始化对象的成分,创建对象。从语义上讲,父类构造方法初始化父类成分,构造父类对象。子类构造方法在父类对象的基础上,初始化子类专有成分,构造子类对象。如果子类继承父类构造方法,那么子类暴露一个接口,返回父类对象,这显然不合理。因此,子类不能继承父类的构造方法。
4、父类的成分只能在父类构造方法中初始化,子类只能初始化自己的专有成分,不能初始化父类的成分,可以在方法内赋值。子类如果初始化父类成分,编译报错:非法的成员初始化,不是基或成员。那么问题来了,子类没有继承父类的构造方法,那么子类如何初始化父类的成分呢?
5、子类不能继承父类的构造方法,但是可以调用父类的构造方法,而且必须调用父类的构造方法,确保父类成分初始化。如果没有显示调用父类的构造方法,会隐式调用父类的default构造方法。子类没有显式调用父类构造方法,父类没有提供default构造方法,编译报错:没有合适的default构造方法可用。
6、构造过程可认为:父类成员初始化列表,父类构造方法内赋值,子类成员初始化列表,子类构造方法内赋值。
7、C++析构方法能不能被继承,是有争议的。个人认为不能继承。有人说,不能继承,为什么子类可以调用。从语义上讲,为什么设计析构方法,析构方法撤销对象的成分。父类析构方法撤销父类的成分,子类构造方法撤销子类专有的成分。
8、析构方法是一种特殊的方法。主要体现在:
a、子类可以显式调用父类的析构方法;
b、子类不能隐藏父类的析构方法;
c、析构方法的重写规则不同,一般的virtual成员方法,重写要求方法名必须相同。析构方法的重写,方法名不同,分别是父类名和子类名。同时,纯虚的成员方法要求子类必须重写,父类可以不实现。纯虚的析构方法也要求子类必须重写(用户不重写,编译器会生成一个重写的析构方法),同时父类必须提供实现,因为必定要调用父类的析构方法。
9、子类构造方法必须调用父类构造方法,与此类似,子类析构方法执行完,必定调用父类的析构方法,可以认为子类析构方法执行完,创建一个对父类析构方法的调用。即使子类析构方法重写了父类的析构方法,子类析构方法执行完,还是要调用父类的析构方法。
10、那么问题来了,不管有没有重写,子类析构方法执行完,都必定要调用父类的析构方法。那么重写析构方法还有什么意义呢?
考虑,指针指向子类,指针的表面类型是父类,delete指针。如果没有重写析构方法,那么delete动作直接调用父类的析构方法,而不是先调用子类的析构方法,再调用父类的析构方法。
11、对象的析构过程可认为:第一步,子类析构方法撤销专有的成分,对于类类型,递归调用析构方法,对于内置类型不需要做什么,可认为不再使用它占用的内存;第二步,调用父类的析构方法,对于类类型,递归调用析构方法,对于内置类型,不需要做什么事,可认为不再使用它占用的内存。
12、什么时候声明析构方法为virtual呢?
当类中有virtual方法时,应该是声明析构方法为virtual,为什么?类中有virtual方法,意味着面向抽象编程,就会有父类指针指向子类对象。这种情况下,为了保证delete父类指针的时候,先调用子类析构方法(撤销子类专有成分),再调用父类析构方法(撤销父类成分),必须将父类析构方法声明为virtual。
如果类中没有virtual方法,不要声明virtual析构方法,为啥?对于virtual,编译器做了一些幕后工作,导致对象变大。
C++ 构造过程和析构过程的更多相关文章
- 【09】绝不在构造和析构过程中调用virtual方法
1.绝不在构造和析构过程中调用virtual方法,为啥? 原因很简单,对于前者,这种情况下,子类专有成分还没有构造,对于后者,子类专有成分已经销毁,因此调用的并不是子类重写的方法,这不是程序员所期望的 ...
- Effective C++ .09 不在构造和析构过程中调用virtual函数
看过C++对象模型的话就可以知道,在构造基类时,完整的vtable没有建立起来(表项没有被相应的子类函数替换),因而无法调用到子类的函数(即构造函数中的virtual函数是本类里的方法,不是virtu ...
- Swift的构造和析构过程
构造过程 Swift的构造过程通过定义构造器来实现. 只是与Objective-C不同的是,Swift的构造器不须要返回值,相同也不须要表明Func. 另外值得提的是,当构造器中为存储型属性赋值时.不 ...
- Swift2.1 语法指南——析构过程
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
- swift学习笔记之-析构过程
//析构过程deist import UIKit /*析构过程(Deinitialization):析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用.析构器用关键字deinit来标示 ...
- 学习Swift -- 析构过程
析构过程 析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用.析构器用关键字deinit来标示,类似于构造器要用init来标示. 原理 Swift 会自动释放不再需要的实例以释放资源, ...
- Swift 析构过程
在一个类的实例被释放之前,析构函数被立即调用.用关键字deinit来标示析构函数,类似于初始化函数用init来标示.析构函数只适用于类类型. 析构过程原理 Swift 会自动释放不再需要的实例以释放资 ...
- php 启动过程 - reqeust RINIT 过程
php 启动过程 - reqeust RINIT 过程 概述 apache 接收到请求之后, 交给 php 处理 php 模块在接收到请求后, 会对请求进行初始化, 及 RINIT 过程 调用触发 a ...
- VScript 函数调用的两种分类:Sub过程和Function过程
来源:http://soft.zdnet.com.cn/software_zone/2007/0925/523318.shtml 在 VBScript 中,过程被分为两类:Sub 过程和 Functi ...
随机推荐
- Number of Rectangles in a Grid
Project Euler 85: Investigating the number of rectangles in a rectangular grid Number of Rectangles ...
- chrome和火狐获取资源
获取网站数据: chrome下获取网站数据可以用如下方式去获取: 而火狐则可以按以下方式获取: 在该目录下找到你想要的数据. 获取本地的数据: chrome下获取本地的数据: firefox下获取本地 ...
- 学习Android之内部类
java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类.内部类又分为:常规内部类.局部内部类.匿名内部类和静态嵌套类四种.我们内部类的知识在Android手机开发中经常用到. 一.常规内部 ...
- c语言变量名称与变量
0x00030 , 0x00031 ,0x00032 ,0x00033 是四个字节,用来存放0x00010(字母a的地址)
- Java内省
什么是内省? Java语言对bean类属性.事件的一种缺省处理方法,例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值. 什么是JavaBean? Java ...
- 我个人有关 Azure 网络 SLA、带宽、延迟、性能、SLB、DNS、DMZ、VNET、IPv6 等的 Azure 常见问题解答
Igor Pagliai(微软) 2014 年 9月 28日上午 5:57 年 11 月 3 年欧洲 TechEd 大会新宣布的内容). 重要提示:这篇文章中我提供的信息具有时间敏感性,因为这些 ...
- mkimage工具 加载地址和入口地址 内核启动分析
第三章第二节 mkimage工具制作Linux内核的压缩镜像文件,需要使用到mkimage工具.mkimage这个工具位于u-boot-2013. 04中的tools目录下,它可以用来制作不压缩或者压 ...
- HNU OJ10320 穿越火线 简单模拟
穿越火线 Time Limit: 10000ms, Special Time Limit:25000ms, Memory Limit:65536KB Total submit users: 12, A ...
- MSP430开学的序章
吐槽一下最近在搞什么~~~,星期三在等板子来,自己的板子,激动呀!!F5系列的板子,激动呀!结果板子到星期五才拿到!开始的时候,感觉自己没多大问题,结果一上手就问题百出,因为没仔细看用户手册,导致光盘 ...
- 【原】Redis-LRU缓存
Redis高级篇 Redis-LRU缓存 将Redis作为缓存使用时,有时添加新数据时,旧数据是很难被清空的. LRU(Least Recently Used) 近期最少使用算法是常用算法之一. 最大 ...