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;
}
这个程序的运行结果如下: