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

Wesley13
• 阅读 734

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

其初始化顺序为:

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

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

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

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

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

如下的测试代码:

#include <iostream>  
#include <string>  
using namespace std;

//抽象类A  
class A
{
public:
    A()
    {
        cout << "抽象类A的构造函数" << endl;
    }
    //纯虚函数fun  
    virtual void fun1() = 0;
};

//抽象类B  
class B
{
public:
    B()
    {
        cout << "抽象类B的构造函数" << endl;
    }
    //纯虚函数fun  
    virtual void fun2() = 0;
};

//普通类C  
class C
{
public:
    C()
    {
        cout << "类C的构造函数" << " 用于虚继承的" << endl;
    }
};

//普通类D  
class D
{
public:
    D()
    {
        cout << "类D的构造函数" << " 用于虚继承的" << endl;
    }
};

//普通类C  
class E
{
public:
    E()
    {
        cout << "类E的构造函数" << endl;
    }
};

//普通类D  
class F
{
public:
    F()
    {
        cout << "类F的构造函数" << endl;
    }
};

//普通类D  
class G
{
public:
    G()
    {
        cout << "类G的构造函数" << endl;
    }
};

//普通类D  
class H
{
public:
    H()
    {
        cout << "类H的构造函数" << endl;
    }
};
//普通类D  
class M
{
public:
    M()
    {
        cout << "类M的构造函数" << endl;
    }
};

class Test : public E, public A, public F, public B, virtual public C, virtual public D
{
public:
    Test() :B(), A(), D(), C(), F(), E()
    {
        cout << "类Test的构造函数" << endl;
    }
    void fun1()
    {
    }
    void fun2()
    {
    }
private:
    G g; // 会自动调用这个数据成员的构造函数
    static H h;
    static M m;
};

H Test::h; // 注意这个定义,非常重要,这就是static类型的成员变量的实现方式

int main(int argc, char* argv[])
{
    cout << "main begin" << endl;
    Test test;
    cout << "main end" << endl;
    return EXIT_SUCCESS;
}

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

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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
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
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
3年前
java常用类(2)
三、时间处理相关类Date类:计算机世界把1970年1月1号定为基准时间,每个度量单位是毫秒(1秒的千分之一),用long类型的变量表示时间。Date分配Date对象并初始化对象,以表示自从标准基准时间(称为“历元”(epoch),即1970年1月1日08:00:00GMT)以来的指定毫秒数。示例:packagecn.tanjian
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这