C++中初始化的顺序问题

C++的初始化顺序非常重要,牢记才能不出常识性的错误。

其初始化顺序为:

1 类中的static成员是最先初始化的,这个是先于main函数的执行的,但是必须注意,如果这个成员只是在类中声明,而没有在类外边进行定义的话,那么这个是不会开辟内存的,是不会初始化的。

2 调用基类的构造函数。但是基类分为两种顺序,特别注意。一种是虚继承的基类;另一种是普通继承的虚基类和普通基类。

虚继承的基类的构造函数是最先调用的,接着虚基类和普通基类的构造函数是按顺序执行的(按照继承的顺序,而不是在类的构造函数中的初始化顺序)。

3 类的数据成员进行初始化,如果是类类型的数据成员就会调用相应的默认构造函数。注意这个顺序是根据类中数据成员定义出现的顺序进行初始化的。

4 最后是进入类自己的构造函数的代码执行

如下的测试代码:

1#include <iostream>   2#include <string>   3using namespace std; 4 5//抽象类A   6class A 7{ 8public: 9    A() 10    { 11        cout << "抽象类A的构造函数" << endl; 12    } 13    //纯虚函数fun   14    virtual void fun1() = 0; 15}; 16 17//抽象类B   18class B 19{ 20public: 21    B() 22    { 23        cout << "抽象类B的构造函数" << endl; 24    } 25    //纯虚函数fun   26    virtual void fun2() = 0; 27}; 28 29//普通类C   30class C 31{ 32public: 33    C() 34    { 35        cout << "类C的构造函数" << " 用于虚继承的" << endl; 36    } 37}; 38 39//普通类D   40class D 41{ 42public: 43    D() 44    { 45        cout << "类D的构造函数" << " 用于虚继承的" << endl; 46    } 47}; 48 49//普通类C   50class E 51{ 52public: 53    E() 54    { 55        cout << "类E的构造函数" << endl; 56    } 57}; 58 59//普通类D   60class F 61{ 62public: 63    F() 64    { 65        cout << "类F的构造函数" << endl; 66    } 67}; 68 69//普通类D   70class G 71{ 72public: 73    G() 74    { 75        cout << "类G的构造函数" << endl; 76    } 77}; 78 79//普通类D   80class H 81{ 82public: 83    H() 84    { 85        cout << "类H的构造函数" << endl; 86    } 87}; 88//普通类D   89class M 90{ 91public: 92    M() 93    { 94        cout << "类M的构造函数" << endl; 95    } 96}; 97 98class Test : public E, public A, public F, public B, virtual public C, virtual public D 99{ 100public: 101    Test() :B(), A(), D(), C(), F(), E() 102    { 103        cout << "类Test的构造函数" << endl; 104    } 105    void fun1() 106    { 107    } 108    void fun2() 109    { 110    } 111private: 112    G g; // 会自动调用这个数据成员的构造函数 113    static H h; 114    static M m; 115}; 116 117H Test::h; // 注意这个定义,非常重要,这就是static类型的成员变量的实现方式 118 119int main(int argc, char* argv[]) 120{ 121    cout << "main begin" << endl; 122    Test test; 123    cout << "main end" << endl; 124    return EXIT_SUCCESS; 125}

这个程序的运行结果如下:

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java常用类(2)

三、时间处理相关类Date类:计算机世界把1970年1月1号定为基准时间,每个度量单位是毫秒(1秒的千分之一),用long类型的变量表示时间。Date分配Date对象并初始化对象,以表示自从标准基准时间(称为“历元”(epoch),即1970年1月1日08:00:00GMT)以来的指定毫秒数。示例:packagecn.tanjian

FLV文件格式

1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.