c++ 类的构造顺序

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

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

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

时间: 2024-08-06 03:45:20

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

java类的初始化顺序

java类的初始化顺序 (2008-10-21 13:30:15) 转载▼ 标签: java 初始化 继承初始化 it 分类: Java 对于静态变量.静态初始化块.变量.初始化块.构造器,它们的初始化顺序依次是(静态变量.静态初始化块)>(变量.初始化块)>构造器.我们也可以通过下面的测试代码来验证这一点: public class InitialOrderTest { // 静态变量 public static String staticField = "静态变量";

javaEE:day2-servlet生命周期、提交解决中文乱码、tomcat加载jar包或类文件的顺序

servlet生命周期 生命周期简介: servlet在服务器第一次被请求的时候new出来,并初始化(即init())再调用service方法.这个实在服务器中new出来,然后用HashMap加的,与客户端无关.客户端之后访问只调用这个servlet的service方法. 具体分为4步: 1 构造方法 :服务器在被客户端第一次请求的时候运行 仅在服务器中运行一次 2 init方法:客户端第一次访问服务器的时候在服务器中进行初始化 仅一次.并且可以通过config参数在 web.xml中通过(ke

C/C++ 多继承(虚继承和构造顺序)

C/C++:一个基类继承和多个基类继承的区别 1.对个基类继承会出现类之间嵌套时出现的同名问题,如果同名变量或者函数出现不在同一层次,则底层派生隐藏外层比如继承基类的同名变量和函数,不会出现二义性,而如果出现在同一阶层, 则会 出现二义性,解决办法:要么在同一阶层的底层(派生类)中重新定义可以解决,或者使用虚继承(减少部分二义性) 2.虚继承保证多次继承相同基类但只有一份基类数据(保证共享); 3.虚继承的构造顺序由编译器按照派生类列表从左往右寻找虚基类函数,先构造虚基类部分,然后按照正常构造从

C和C++的面向对象专题(7)——单例模式解决静态成员对象和全局对象的构造顺序难题

本专栏文章列表 一.何为面向对象 二.C语言也能实现面向对象 三.C++中的不优雅特性 四.解决封装,避免接口 五.合理使用模板,避免代码冗余 六.C++也能反射 七.单例模式解决静态成员对象和全局对象的构造顺序难题 八.更为高级的预处理器PHP 七.单例模式解决静态成员对象和全局对象的构造顺序难题 上回书说道,我们的程序有一个隐藏的漏洞,如果ClassRegister这个类所在的.o文件,如果在所有.o文件中是第一个被链接的的,那么就不会出问题. 这么说太抽象了,让我们画个图表 ClassRe

对象的构造顺序(十六)

在 C++ 中的类可以定义多个对象,那么对象构造的顺序是怎样的呢?对于局部对象:当程序执行流到达对象的定义语句时进行构造.我们以代码为例进行分析 #include <stdio.h> class Test { private:     int mi; public:     Test(int i)     {         mi = i;                  printf("Test(int i): %d\n", mi);     }          Te

c++构造顺序

1. 静态成员最先构造,按照静态成员初始化顺序,不是类里面的声明顺序 2. 父类构造 3. 非静态成员构造,按照类成员声明顺序,不是逗号初始化成员顺序 4. 自身构造函数 Demo: class TestA { public: TestA(){ std::cout << "TestA()" << std::endl; } }; class TestB { public: TestB(int b) { std::cout << "TestB(

第21课对象的构造顺序

对象的构造顺序一C++中的类可以定义多个对象,那么对象的构造顺序是怎样的呢?对于局部对象当程序执行流到达对象的定义语句时进行构造对象定义------>构造 原文地址:https://www.cnblogs.com/-glb/p/11846137.html

JVM查找类文件的顺序

Java虚拟机(JVM Java Virtual Machine)查找类文件的顺序 1.如果没有配置classpath环境变量,JVM只在当前目录下查找要运行的类文件. 2.如果配置了classpath环境,JVM会先在classpath环境变量值的目录中查找要运行的类文件. 3.classpath环境变量值的结尾处如果加上分号,那么JVM在classpath目录下没有找到要指定的类文件,会在当前目录下在查找一次. 4.classpath环境变量值的结尾出如果没有分号,那么JVM在classpa

Delphi2010新发现-类的构造和析构函数功能

Delphi2010发布了. 虽然凭着对Delphi的热爱第一时间就安装了,但是现在可能是年纪大了,对新事物缺乏兴趣了.一直都没有仔细研究. 今天有点时间试了一下新功能. 本来C#和Delphi.NET是支持类的构造函数/析构函数的(注意不是实例的构造和析构).也就是在模块初始化/卸载的时候会调用. 这样有很多好处,比如说类的静态变量的初始化什么的都可以在这里做. Delphi For Win32对这方面的需求还不是很大. 第一个原因.历史上旧版Delphi不支持静态变量.只能用Unit的全局变