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

class A {
public:
A() {
cout << "A" << endl;
}
~A() {
cout << "~A" << endl;
}
}; class B : public A {
public:
B() {
cout << "B" << endl;
}
~B() {
cout << "~B" << endl;
}
};

结果为:

A
B
~B
~A

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

class A {
public:
A() {
cout << "A" << endl;
}
~A() {
cout << "~A" << endl;
}
};
class B{
public:
B() {
cout << "B" << endl;
}
~B() {
cout << "~B" << endl;
}
}; class C : public B, public A {
public:
C() {
cout << "C" << endl;
}
~C() {
cout << "~C" << endl;
}
};

输出:

B
A
C
~C
~A
~B

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

class A {
public:
A() {
cout << "A" << endl;
}
~A() {
cout << "~A" << endl;
}
};
class B : public A {
public:
B() {
cout << "B" << endl;
}
~B() {
cout << "~B" << endl;
}
};
class C : public B, public A {
public:
C() {
cout << "C" << endl;
}
~C() {
cout << "~C" << endl;
}
};
class D : public B {
public:
D() {
cout << "D" << endl;
}
~D() {
cout << "~D" << endl;
}
private:
C c;
A a;
};

输出结果为:

A  // D 继承 B,B 继承 A,所以顺序为 A, B
B
A // 定义 C 的对象,C 继承顺序中第一个是 B,B 继承 A,所以是 A, B
B
A // C 继承顺序中的第二个
C // C 的定义
A // D 中参数 A
D
~D
~A
~C
~A
~B
~A
~B
~A

类内声明:

class D {
public:
D(int a) {
cout << "D: " << a << endl;
}
}; class M {
public:
M() {
cout << 'M' << endl;
extern D d;
}
};

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

包含 static 变量:

class M {
public:
M() {
cout << 'M' << endl;
}
private:
static D d;
};

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

多区段下构造成员顺序:

class A {
public:
A() {
cout << "A" << endl;
}
~A() {
cout << "~A" << endl;
}
};
class B{
public:
B() {
cout << "B" << endl;
}
~B() {
cout << "~B" << endl;
}
};
class D {
private:
A a;
B b;
public:
D() {
cout << "D" << endl;
}
~D() {
cout << "~D" << endl;
}
private:
B b2;
A a2;
};

输出结果:

A
B
B
A
D
~D
~A
~B
~B
~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. 【刷题】BZOJ 3529 [Sdoi2014]数表

    Description 有一张n×m的数表,其第i行第j列(1<=i<=n,1<=j<=m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. In ...

  2. Android 捕获组合键

    android中捕获组合键http://blog.csdn.net/wenlibin1985/article/details/5579359 Android组合键http://www.eoeandro ...

  3. python之旅:函数对象、函数嵌套、名称空间与作用域、装饰器

    一 函数对象 一 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 二 利用该特性,优雅的取代多分支的if de ...

  4. Express入门( node.js Web应用框架 )

    运用Express框架构建简单的NodeJS应用 Start  确认安装了NodeJS之后(最新的Node安装好后NPM也会自带安装了),npm可理解为nodejs的一个工具包.可通过查看版本来检测是 ...

  5. 文档比较比对工具Beyond Compare

    Beyond Compare 可以比较文件夹或文件

  6. UIScrollview 与 Autolayout 的那点事

    原文  http://www.cocoachina.com/ios/20151221/14757.html 前言 自从写了 介绍Masonry 那篇文章以后 就一直有人对UIScrollView的那个 ...

  7. lumen passport Call to undefined method Laravel\Lumen\Application::group()

    解决方法:https://github.com/dusterio/lumen-passport/issues/69 public function boot() { LumenPassport::ro ...

  8. linux基础命令之sed

    什么是sed? sed是一个流编辑器,英文全名为stream editor,流的意思就是能处理文件或者通过管    道传输来的数据.主要针对行,也就是行编辑.默认是不编辑文件的,处理时,把当前    ...

  9. 使用docker配置etcd集群

    docker配置etcd集群与直接部署etcd集群在配置上并没有什么太大差别. 我这里直接使用docker-compose来实现容器化的etcd部署 环境如下: HostName IP etcd1 1 ...

  10. 线性回归,感知机,逻辑回归(GD,SGD)

    线性回归 线性回归是一个回归问题,即用一条线去拟合训练数据 线性回归的模型: 通过训练数据学习一个特征的线性组合,以此作为预测函数. 训练目标:根据训练数据学习参数(w1,w2, ... , wn,b ...