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++ 构造过程和析构过程的更多相关文章

  1. 【09】绝不在构造和析构过程中调用virtual方法

    1.绝不在构造和析构过程中调用virtual方法,为啥? 原因很简单,对于前者,这种情况下,子类专有成分还没有构造,对于后者,子类专有成分已经销毁,因此调用的并不是子类重写的方法,这不是程序员所期望的 ...

  2. Effective C++ .09 不在构造和析构过程中调用virtual函数

    看过C++对象模型的话就可以知道,在构造基类时,完整的vtable没有建立起来(表项没有被相应的子类函数替换),因而无法调用到子类的函数(即构造函数中的virtual函数是本类里的方法,不是virtu ...

  3. Swift的构造和析构过程

    构造过程 Swift的构造过程通过定义构造器来实现. 只是与Objective-C不同的是,Swift的构造器不须要返回值,相同也不须要表明Func. 另外值得提的是,当构造器中为存储型属性赋值时.不 ...

  4. Swift2.1 语法指南——析构过程

    原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...

  5. swift学习笔记之-析构过程

    //析构过程deist import UIKit /*析构过程(Deinitialization):析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用.析构器用关键字deinit来标示 ...

  6. 学习Swift -- 析构过程

    析构过程 析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用.析构器用关键字deinit来标示,类似于构造器要用init来标示. 原理 Swift 会自动释放不再需要的实例以释放资源, ...

  7. Swift 析构过程

    在一个类的实例被释放之前,析构函数被立即调用.用关键字deinit来标示析构函数,类似于初始化函数用init来标示.析构函数只适用于类类型. 析构过程原理 Swift 会自动释放不再需要的实例以释放资 ...

  8. php 启动过程 - reqeust RINIT 过程

    php 启动过程 - reqeust RINIT 过程 概述 apache 接收到请求之后, 交给 php 处理 php 模块在接收到请求后, 会对请求进行初始化, 及 RINIT 过程 调用触发 a ...

  9. VScript 函数调用的两种分类:Sub过程和Function过程

    来源:http://soft.zdnet.com.cn/software_zone/2007/0925/523318.shtml 在 VBScript 中,过程被分为两类:Sub 过程和 Functi ...

随机推荐

  1. Android开发之异步消息处理机制Handler

    更加详细的介绍Handler的博文-http://blog.csdn.net/guolin_blog/article/details/9991569 Android中的异步消息处理主要有四个部分组成, ...

  2. poj 2151 Check the difficulty of problems(概率dp)

    poj double 就得交c++,我交G++错了一次 题目:http://poj.org/problem?id=2151 题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 问 ...

  3. bzoj1789 AHOI 维护数列(线段树)

    首先想到线段树,然后刚开始写忽然想到树状数组求和岂不是更快,而且编程复杂度又小,于是把之前写的删掉,写树状数组,写完模版之后忽然发现这题竟然是区间修改! 于是又删掉重写,忽然发现不会处理又加又乘的,果 ...

  4. JSOI2007文本生成器

    1030: [JSOI2007]文本生成器 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1613  Solved: 656[Submit][Statu ...

  5. POJ 3281 Dining (网络流构图)

    [题意]有F种食物和D种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料.现在有N头牛,每头牛都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几头牛同时享用到自己喜欢的食物和 ...

  6. linux下nagios的安装与部署

    一.Nagios简介 Nagios是一款开源的电脑系统和网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系统或服务状态异常时发出邮件或短信报 ...

  7. 多线程程序设计学习(7)read-write lock pattern

    Read-Write Lock Pattern[读写]一:Read-Write Lock Pattern的参与者--->读写锁--->数据(共享资源)--->读线程--->写线 ...

  8. TPL

    namespace TPLTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } pr ...

  9. mysql日期加减问题

    有一个date列,我想修改下,让该列里每个日期都加上7天,怎么写代码?  update [表名] set date=date_add(date, interval 7 day); SELECT * f ...

  10. SGU223 - Little Kings(状态压缩DP)

    题目大意 给定一个N*N(n<=10,k<=n*n)大小的棋盘,要求你在棋盘上放置k个国王,使得不会相互攻击,如果棋盘上某个格子放置了一个国王,那么与他相邻的八个格子都是他的攻击范围,问有 ...