构造函数初始化列表顺序

构造函数初始化列表仅用于初始化成员的值,并不指定这些初始化执行的次序。成员被初始化的次序就是定义成员的次序。第一个被定义的成员先被初始化,依次类推。一般,初始化的顺序无关紧要,然而,如果一个成员是根据其他成员而初始化,则成员的初始化顺序是至关重要的。

class x {
  int   i;//声明顺序是先i,后j,故初始化列表中,会先初始化i,再初始化j
  int   j;
public:
    x(int  tem): j(tem),i(j){}    /*看起来是先初始化j,然后初始化i,其实恰恰相反,
        先用未初始化的j来初始化i,虽然编译器不会提示你什么,但是j未初始化它便由计
        算机随即分配的内存存储,它的值也是随即的,这个值可能不是你想要的,错误就
        出现了。将i和j的声明顺序调过来就没有问题了。*/
};


总的来说,有虚基类时,初始化列表调用构造函数初始化的顺序如下:

1)虚基类的构造函数

2)根据派生类声明的顺序调用派生类的构造函数,对虚基类构造函数的调用被忽略

3)根据派生类对象声明的顺序调用对象所属派生类的虚基类构造函数、对象所属派生类的构造函数

无虚基类时,初始化列表调用构造函数初始化的顺序如下:

1)根据派生类声明的顺序调用对象所属派生类的基类构造函数、接着是派生类的构造函数

2)根据派生类对象声明的顺序调用对象所属派生类的基类构造函数、对象所属派生类的构造函数

你可以把我的例子运行一下,你就什么都清楚了!

#include<stdio.h>  
#include<stdlib.h>  
#include "iostream"
using namespace  std;
class Base
{
public:
	/*Base()
	{
		cout<<"Base 构造\t"<<n<<endl;
	};*/
	Base(int num)
	{
		n=num;
		cout<<"Base 构造\t"<<n<<endl;
	};
	~Base()
	{
		cout<<"Base 销毁\t"<<n<<endl;
	};
	 void show()
	{
		cout<<"base show"<<endl;
	};
protected:
private:
      int n;
};

class A:public Base
{
public:
	A(int num):Base(4)
	{
		n=num;
		cout<<"A 构造\t"<<n<<endl;
	};
	~A()
	{
		cout<<"A 销毁\t"<<n<<endl;
	};
	void show(int y)
	{
		cout<<"A show"<<endl;
	};
	
protected:
private:
	int n;
};

#include "stdafx.h"  
#include "testCplus.h"  
//Base base2(2);
//static Base base1(1);
//int  Base::n=9;
int main()
{
	//Base *pBase;
	//Base base3(3);
	//{
	//	Base base4(4);
	//	pBase=new Base(5);
	//	static Base base6(6);
	//}
	//delete pBase;
	A a1(2);
	A a2(3);
	/*Base *pb=&a;
	pb->show();*/
	//((A *)pb)->show(0);
	/*Base b(6);
	pb=&b;
	pb->show();*/

	return 0;
}


你可能感兴趣的:(构造函数初始化列表顺序)