总结笔记-c++成员变量、构造函数以及析构函数的执行顺序

在我的之前的博客http://blog.csdn.net/caoyan_12727/article/details/52356844有提到c++各种变量的初始化规则,本文将总结c++中涉及到的各种变量的初始化顺序和析构函

以及构造函数初始化的顺序!!

第一步:类的静态成员变量

#include 
#include 
#include 
#include 
#include
using namespace std;

class a{
public:
	int a1;
	int a2;
	static int a3;
	a(int x) :a1(x){
		a2 = 2;
		a3 = 7;
	}
};

//int a::a3 = 4;

int main(){
	a aa(2);
	cout << a::a3 << endl;
	return 0;
}
我们把int a::a3这一行注释掉,vs2103编译器提示错误:


直接显示未定义的外部变量,说明在类中的static int a3语句连定义都算不上,一定要在类外进行定义!!!

第二步:全局变量和类中静态变量的执行顺序:

测试程序:

#include 
#include 
#include 
#include 
#include 
#include
#include 
#include 
using namespace std;
struct B{
	B(){ std::cout << "b\n"; }
};
struct C{
	C(){ std::cout << "c\n"; }
};
struct D{
	D(){ std::cout << "d\n"; }
};
struct E{
	E(){ std::cout << "e\n"; }
};
struct F{
	F(){ std::cout << "f\n"; }
};
struct A{
	static B b;
	D d;
	C c;
	A() :d(), c(){}
};
struct AA :A{
	static E e;
};

F f;
B A::b;
E AA::e;
int main(){
	A a;
	return 0;
}
测试结果:

总结笔记-c++成员变量、构造函数以及析构函数的执行顺序_第1张图片

替换顺序:

B A::b;
F f;
E AA::e;

测试结果:

总结笔记-c++成员变量、构造函数以及析构函数的执行顺序_第2张图片

可以看到,在全局变量、父类静态变量子类静态变量同时存在的情况下,初始化规则是按照它们定义的先后顺序进行的,同时在类中,比如在类A中,成员c和成员d的初始化顺序和它们的定义顺序是一样的,即先初始化成员d,然后初始化成员c!!!因为类的静态成员同样被存储在.data段,它们可以看做是带有“特殊作用域的全局变量”。

第三步:基类和虚基类的析构函数和构造函数的调用顺序

测试代码:

#include 
#include 
#include 
#include 
#include 
#include
using namespace std;

class a{
public:
	int a1;
	int a2;
	a(int x) :a1(x){
		cout << "construct class a!" << endl;
	}
	~a(){
		cout << "discontruct class a!" << endl;
	}
};

class b{
public:
	int b1;
	int b2;
	b(int x) :b1(x){
		cout << "construct class b!" << endl;
	}
	~b(){
		cout << "discontruct class b!" << endl;
	}
};

class d{
public:
	int d1;
	int d2;
	d(){
		cout << "construct class d!" << endl;
	}
	~d(){
		cout << "distconruct class d!" << endl;
	}
};

class e{
public:
	int e1;
	int e2;
	e(){
		cout << "construct class e!" << endl;
	}
	~e(){
		cout << "discontruct class e!" << endl;
	}
};

class c :virtual public d, public  b, public a, virtual public e{
public:
	int c1;
	int c2;
	c(int x, int y, int z) :a(y), b(z), c1(x){
		cout << "construct clsss c! " << endl;
	}
	~c(){
		cout << "discontruct class c!" << endl;
	}
};

int con(){
	c two(1, 2, 3);
	return 0;
}

int main(){
	con();
	return 0;
}
测试输出:

总结笔记-c++成员变量、构造函数以及析构函数的执行顺序_第3张图片

修改继承顺序:

class c :virtual public e, public  a, public b, virtual public d{
public:
	int c1;
	int c2;
	c(int x, int y, int z) :a(y), b(z), c1(x){
		cout << "construct clsss c! " << endl;
	}
	~c(){
		cout << "discontruct class c!" << endl;
	}
};
输出结果:

总结笔记-c++成员变量、构造函数以及析构函数的执行顺序_第4张图片

在例子中类c虚拟继承类d和类e,普通继承类a和类吧,从构造函数可以看出,在同一层次的继承中,虚拟继承的构造函数要先于非虚拟继承的构造函数,在同一层的所有非虚拟继承的类中,其构造函数的执行顺序是先左后右,同样的在同一层所有非虚拟继承的类中,构造函数的执行也是先左后右,和类的定义顺序无关!!无关!!

struct B{
public:
	int b1;
	int b2;
	B(int x,int y):b1(x),b2(y){
		cout << "b" << endl;
	}
};
struct D{
public:
	D(){
		cout << "d" << endl;
	}
};
struct C{
public:
	D d;
	B b;
	C():b(1,2){ std::cout << "c\n"; }
};

int main(){	
	C c;
	return 0;
}
输出结果:
总结笔记-c++成员变量、构造函数以及析构函数的执行顺序_第5张图片


第四步:函数中的局部静态变量初始化

struct B{
	int b1 = 1;
	B(){ std::cout << "b\n"; }
};

struct C{
	int c1 = 2;
	C(){ std::cout << "c\n"; }
};

struct D{
	int d1 = 3;
	D(){ std::cout << "d\n"; }
};

struct E{
	int e1 = 4;
	E(){ std::cout << "e\n"; }
};

struct F{
	int f1 = 5;
	F(){ std::cout << "f\n"; }
};

void func(){
	static D d;
}

B b;
C c;
static F f;

int main(){	
	E e;
	func();
	return 0;
}
测试结果:

总结笔记-c++成员变量、构造函数以及析构函数的执行顺序_第6张图片

所以总结一下c++的变量初始化顺序:

(1)先初始化全局变量和全局静态变量(不管是不是类里面的静态变量,因为此时类中的静态变量会被当做全局变量看待),如果有局部静态变量,则在局部函数被调用时,它里面的局部静态变量才会初始化;不管是基类中的静态变量还是派生类中的静态变量,它们都存储在.data段,会被当做全局变量来看待,所以它的初始化和它们的定义顺序一致!!!

(2)在成员初始化列表中,成员初始化的顺序和定义的顺序一致,和在初始化列表里出现的顺序无关;

你可能感兴趣的:(c++)