探究类对象在创建时各成员的构造顺序

一、先看一个简单的例子:

class B
{
public:
	B(){cout<<"B constructor"<<endl;}
private:
	int m;
	int n;
};

int _tmain(int argc, _TCHAR* argv[])
{
	B b1;
	system("pause");

	return 0;
}

完成b1对象的构造前,它会先构造类的数据成员(此处为m和n),然后再进入到类B的构造函数,所以显示的结果如下:

B constructor
请按任意键继续. . .

为了显示更清晰,我们增加一个类A,将类B中的数据成员m和n改为类A的对象a1、a2。
class A
{
public:
	A(){cout<<"A default constructor"<<endl;}
	A(int n){cout<<"A int constructor, n = "<<n<<endl;}
};

class B
{
public:
	B(){cout<<"B constructor"<<endl;}
private:
	A m;
	A n;
};
显示结果为:
A default constructor
A default constructor
B constructor
请按任意键继续. . .

二、上面的还是比较简单的,若考虑“成员初始化列表”呢

class A
{
public:
	A(){cout<<"A default constructor"<<endl;}
	A(int n){cout<<"A int constructor, n = "<<n<<endl;}
};

class B
{
public:
	B():a1(2){a2=3;cout<<"B constructor"<<endl;}
private:
	A a1;
	A a2;
};

int _tmain(int argc, _TCHAR* argv[])
{
	B b1;
	system("pause");

	return 0;
}
结果:
A int constructor, n = 2
A default constructor
A int constructor, n = 3
B constructor
请按任意键继续. . .

分析看看顺序,
1. 构造成员变量a1,而a1通过成员初始化变量赋值为2了,所以调用类A的构造函数A(int n);
2. 构造成员变量a2,没有初始化,所以直接调用A();
3. 进入类B的构造函数,运行赋值语句“a2=3”,此时会通过A(int n)构造一个临时的对象,然后再拷贝给a2;

4. 输出B constructor;

与显示结果一致 oh yeah~~~

三、再加大难度,增加类的继承

#include "stdafx.h"
#include<iostream>
using namespace std;

class Z
{
public:
	Z(){cout<<"Z default constructor"<<endl;}
	Z(int n){cout<<"Z int constructor, int n = "<<n<<endl;}
};

class A
{
public:
	A()
	{
		y=1;
		cout<<"A constructor"<<endl;
	}
	Z x;
	Z y;
};

class B : public A
{
public:
	B():n(3),m(2)
	{
		cout<<"B constructor"<<endl;
	}
	Z m;
	Z n;
};

int _tmain(int argc, _TCHAR* argv[])
{
	B b1;
	system("pause");

	return 0;
}
结果如下:
Z default constructor
Z default constructor
Z int constructor, int n = 1
A constructor
Z int constructor, int n = 2
Z int constructor, int n = 3
B constructor
请按任意键继续. . .

其实,也很容易分析,需要明确一点,派生类对象构造前,会先构造基类的对象,所以可以分成两部分来看:
1. 基类A对象的创建
    1) 构造成员变量x,调用Z();
    2) 构造成员变量y,调用Z();
    3) 进入A(),运行赋值语句“y=1”,此时会通过Z(int n)构造一个临时的对象,然后再拷贝给y;
    4) 输出A constructor
2. 派生类B对象的创建
    1) 构造成员变量m,而m通过成员初始化变量赋值为2了,所以调用类Z的构造函数Z(int n);
    2) 构造成员变量n,而n通过成员初始化变量赋值为3了,所以调用类Z的构造函数Z(int n);
    3) 进入进入B(),输出B constructor

现在,大家应该对对象创建时各成员的构造顺序有一定的了解了吧,析构函数调用的顺序与构造函数相反,此处就不展开分析了,有兴趣的同学可以自己去实践实践。





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值