在单继承的情况下,父类构造先于子类,子类析构先于父类,例:

  1. class A {
  2. public:
  3. A() {
  4. cout << "A" << endl;
  5. }
  6. ~A() {
  7. cout << "~A" << endl;
  8. }
  9. };
  10.  
  11. class B : public A {
  12. public:
  13. B() {
  14. cout << "B" << endl;
  15. }
  16. ~B() {
  17. cout << "~B" << endl;
  18. }
  19. };

结果为:

  1. A
  2. B
  3. ~B
  4. ~A

在多继承的情况下,此时的构造顺序在满足单继承构造顺序要求的情况下,出现了两个同级父类的构造顺序问题。在这个时候,对于同级父类,构造顺序是根据继承列表从左往右的。析构顺序相反。

  1. class A {
  2. public:
  3. A() {
  4. cout << "A" << endl;
  5. }
  6. ~A() {
  7. cout << "~A" << endl;
  8. }
  9. };
  10. class B{
  11. public:
  12. B() {
  13. cout << "B" << endl;
  14. }
  15. ~B() {
  16. cout << "~B" << endl;
  17. }
  18. };
  19.  
  20. class C : public B, public A {
  21. public:
  22. C() {
  23. cout << "C" << endl;
  24. }
  25. ~C() {
  26. cout << "~C" << endl;
  27. }
  28. };

输出:

  1. B
  2. A
  3. C
  4. ~C
  5. ~A
  6. ~B

类中包含类对象的情况下的构造顺序:

  1. class A {
  2. public:
  3. A() {
  4. cout << "A" << endl;
  5. }
  6. ~A() {
  7. cout << "~A" << endl;
  8. }
  9. };
  10. class B : public A {
  11. public:
  12. B() {
  13. cout << "B" << endl;
  14. }
  15. ~B() {
  16. cout << "~B" << endl;
  17. }
  18. };
  19. class C : public B, public A {
  20. public:
  21. C() {
  22. cout << "C" << endl;
  23. }
  24. ~C() {
  25. cout << "~C" << endl;
  26. }
  27. };
  28. class D : public B {
  29. public:
  30. D() {
  31. cout << "D" << endl;
  32. }
  33. ~D() {
  34. cout << "~D" << endl;
  35. }
  36. private:
  37. C c;
  38. A a;
  39. };

输出结果为:

  1. A // D 继承 B,B 继承 A,所以顺序为 A, B
  2. B
  3. A // 定义 C 的对象,C 继承顺序中第一个是 B,B 继承 A,所以是 A, B
  4. B
  5. A // C 继承顺序中的第二个
  6. C // C 的定义
  7. A // D 中参数 A
  8. D
  9. ~D
  10. ~A
  11. ~C
  12. ~A
  13. ~B
  14. ~A
  15. ~B
  16. ~A

类内声明:

  1. class D {
  2. public:
  3. D(int a) {
  4. cout << "D: " << a << endl;
  5. }
  6. };
  7.  
  8. class M {
  9. public:
  10. M() {
  11. cout << 'M' << endl;
  12. extern D d;
  13. }
  14. };

上面的写法不报错,因为没有进行对象的定义,只有对象的声明。所以不需要调用D的构造函数。

包含 static 变量:

  1. class M {
  2. public:
  3. M() {
  4. cout << 'M' << endl;
  5. }
  6. private:
  7. static D d;
  8. };

在不进行 static 对象的定义的情况下,进行 M 对象的定义是不报错的,因为没有用到 D 类的构造函数。也即是 d 只进行了声明没有进行定义。

多区段下构造成员顺序:

  1. class A {
  2. public:
  3. A() {
  4. cout << "A" << endl;
  5. }
  6. ~A() {
  7. cout << "~A" << endl;
  8. }
  9. };
  10. class B{
  11. public:
  12. B() {
  13. cout << "B" << endl;
  14. }
  15. ~B() {
  16. cout << "~B" << endl;
  17. }
  18. };
  19. class D {
  20. private:
  21. A a;
  22. B b;
  23. public:
  24. D() {
  25. cout << "D" << endl;
  26. }
  27. ~D() {
  28. cout << "~D" << endl;
  29. }
  30. private:
  31. B b2;
  32. A a2;
  33. };

输出结果:

  1. A
  2. B
  3. B
  4. A
  5. D
  6. ~D
  7. ~A
  8. ~B
  9. ~B
  10. ~A

就像上述代码,不管交换访问区还是访问权限,始终都是按照从上到下的顺序进行构造.

c++ 类的构造顺序的更多相关文章

  1. Java语法专题1: 类的构造顺序

    合集目录 Java语法专题1: 类的构造顺序 问题 下面的第二个问题来源于Oracle的笔试题, 非常经典的一个问题, 我从07年开始用了十几年. 看似简单, 做对的比例不到2/10. 描述一下多级继 ...

  2. c# 衍生类和基类的构造顺序

    public class MyDeriveClass :MyBaseClass { public MyDeriveClass() :base() { } int derive_int = 1; } p ...

  3. C++浅析——继承类中构造和析构顺序

    先看测试代码,CTEST 继承自CBase,并包含一个CMember成员对象: static int nIndex = 1; class CMember { public: CMember() { p ...

  4. C++类继承中,基类/当前对象属性/当前对象的构造顺序

    [1]中提到,规范的派生类构造函数三个要点: 首先创建基类对象 应通过成员初始化列表,创建基类对象 应该初始化本派生类新增的成员变量 那在构造派生类实例的过程中,其基类(以及多继承的时候多个基类)/当 ...

  5. 10.C++-构造函数初始化列表、类const成员、对象构造顺序、析构函数

    首先回忆下,以前学的const 单独使用const修饰变量时,是定义的常量,比如:const int i=1; 使用volatile const修饰变量时,定义的是只读变量 使用const & ...

  6. C/C++ 多继承{虚基类,虚继承,构造顺序,析构顺序}

    C/C++:一个基类继承和多个基类继承的区别 1.对多个基类继承会出现类之间嵌套时出现的同名问题,如果同名变量或者函数出现不在同一层次,则底层派生隐藏外层比如继承基类的同名变量和函数,不会出现二义性, ...

  7. java类的初始化顺序

    在java中,当我们new一个对象时,对象中的成员,初始化块以及构造方法的加载是有一定的顺序的,看下面一副图: 一.单类(无基类)下的初始化顺序: public class Parent { stat ...

  8. C#多态;父类引用指向子类对象;new和override的区别;new、abstract、virtual、override,sealed关键字区别和使用代码示例;c#类的初始化顺序

    关于父类引用指向子类对象 例如: 有以下2个类 public class Father { public int age = 70; public static string name = " ...

  9. C++ 类 、构造、 析构、 重载 、单例模式 学习笔记及练习

    一.拷贝构造函数 1.是一种特殊的构造函数,就是用一个已有的对象去构造其同类的副本对象,即对象克隆. class 类名 { 类名(类名& that) { 对类成员挨个赋值 ... } } 练习 ...

随机推荐

  1. [BZOJ4044]Virus synthesis 回文自动机的DP

    4044: [Cerc2014] Virus synthesis Time Limit: 20 Sec  Memory Limit: 128 MB Description Viruses are us ...

  2. 【BZOJ4004】【JLOI2015】装备购买

    Description 脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,用向量zi(aj ,.....,am) 表示 (1 <= i <= n; 1 < ...

  3. 【Learning】积性函数前缀和——洲阁筛(min_25写法)

    问题描述 洲阁筛解决的问题主要是\(n\)范围较大的积性函数前缀和. ​ 已知一积性函数\(f(i)\),求\(\sum_{i=1}^nf(i)\). \(n\leq10^{12}\). 求解方法 如 ...

  4. digitalworld.local: MERCY靶机入侵

    0x01 前言 MERCY是一个致力于PWK课程安全的靶机系统.MERCY是一款游戏名称,与易受攻击的靶机名称无关.本次实验是攻击目标靶机获取root权限并读系统目录中的proof.txt信息 靶机的 ...

  5. Git 常用操作(二)

    第一次传数据:echo "# miya" >> README.mdgit initgit add README.mdgit commit -m "first ...

  6. Error while uploading slice_4.apk : WARNING: linker: libhoudini.so has text relocations. This is wasting memory and prevents security hardening. Please fix.

    问题: android studio 2.4版本新建项目后老是编译不过,查看log报如下错误,最后发现关闭即时编译功能可以解决此问题.这也算是2.4测试版的bug吧 android - Error w ...

  7. 轻量高效的开源JavaScript插件和库 【转】

    图片 布局 轮播图 弹出层 音频视频 编辑器 字符串 表单 存储 动画 时间 其它 加载器 构建工具 测试 包管理器 CDN 图片 baguetteBox.js - 是一个简单易用的响应式图像灯箱效果 ...

  8. R语言的ARIMA模型预测

    R通过RODBC连接数据库 stats包中的st函数建立时间序列 funitRoot包中的unitrootTest函数检验单位根 forecast包中的函数进行预测 差分用timeSeries包中di ...

  9. Chapter7(类) --C++Prime笔记

    类(关键词):数据抽象(数据成员和函数成员),封装(private),构造函数,静态成员 1.判断一个类是否是抽象数据类型,可以看我们对这个类的操作是对你内的数据成员操作,自己编写相应的处理函数,还是 ...

  10. micro 架构组件介绍

    Micro 是什么 Micro 是微服务生态系统中专注于提供产品.服务和解决方案的一款软件,使得在现代软件企业中起到创新驱动.它计划是可以将任何微服务相关的资源与即将使用此款软件的公司结合起来,利用此 ...