《C++新经典对象模型》之第6章 对象构造语义学

6.1 继承体系下的对象构造

6.1.1 对象的构造顺序

从父类到子类,从根源到末端。
先成员变量(定义顺序,从上到下),后构造函数(先初始化列表,后函数体)。

析构顺序:与构造顺序相反。
从子类到父类,先析构函数,后成员变量(从下到上)。

C::成员变量1构造函数	//7
C::成员变量2构造函数	//8
C::C()	//9
	B::成员变量1构造函数	//4
	B::成员变量2构造函数	//5
	B::B()	//6
		A::成员变量1构造函数	//1
		A::成员变量2构造函数	//2
		A::A()	//3
			构造函数初始化列表
			构造函数函数体
		
		A::~A()	//7
		A::成员变量2析构函数	//8
		A::成员变量1析构函数	//9
	B::~B()	//4
	B::成员变量2析构函数	//5
	B::成员变量1析构函数	//6
C::~C()	//1
C::成员变量2析构函数	//2
C::成员变量1析构函数	//3

6.1.2 虚函数

给虚函数表指针赋值的语句,编译器会插入到构造函数的函数体之前。

C::C()
	B::B()	
		A::A()
			vptr = A::vftable;	//虚函数表指针赋值
			A构造函数初始化列表
			A构造函数函数体
		vptr = B::vftable;
		B构造函数初始化列表
		B构造函数函数体
	vptr = C::vftable;
	C构造函数初始化列表
	C构造函数函数体

6.1.3 构造函数中对虚函数的调用

(1)构造函数中调用虚函数,并不通过虚函数表来调用,而是直接调用(虚函数有真实地址)。
(2)在构造函数中调用的虚函数从所在类往根类回溯,逐次找这个虚函数,找到哪个就直接调用(静态方式)。
(3)构造函数中调用虚函数时,对象未构造完整,不宜采用虚函数表机制调用虚函数。
(4)不要在类的构造函数和析构函数中调用虚函数。

#include <iostream>
using namespace std;

namespace _n1
{
   
	class TA
	{
   
	public:
		TA()
		{
   
			cout << "TA::TA(), this = " << this << endl;
		}
		~TA()
		{
   
			cout << "TA::~TA(), this = " << this << endl;
		}
	};

	class TB
	{
   
	public:
		TB()
		{
   
			cout << "TB::TB(), this = " << this << endl;
		}
		~TB()
		{
   
			cout << "TB::~TB(), this = " << this << endl;
		}
	};

	class T1
	{
   
	public:
		T1()
		{
   
			cout << "T1::T1(), this = " << this << endl;
		}
		~T1()
		{
   
			cout << "T1::~T1(), this = " << this << endl;
		}
	};

	class T2 : public T1
	{
   
	public:
		T2()
		{
   
			cout << "T2::T2(), this = " << this << endl;
		}
		~T2()
		{
   
			cout << "T2::~T2(), this = " << this << endl;
		}
	};

	class T3 : public T2
	{
   
	public:
		T3()
		{
   
			cout << "T3::T3(), this = " << this << endl;
		}
		~T3()
		{
   
			cout << "T3::~T3(), this = " << this << endl;
		}

	private:
		TA ta;
		TB tb;
	};
}

namespace _n2
{
   
	class A
	{
   
	public:
		A()
		{
   
			myvirfunc();
			cout << "A::A(), this = " << this << endl;
		}
		virtual ~A()
		{
   
			myvirfunc();
			cout << "A::~A(), this = " << this << endl;
		}

	public:
		virtual void myvirfunc()
		{
   
			myvirfunc2();
			cout << "A::myvirfunc(), this = " << this << endl;
		}
		virtual void myvirfunc2()
		{
   
			cout << "A::myvirfunc2(), this = " << this << endl;
		}
	};

	class B : public A
	{
   
	public:
		B()
		{
   
			myvirfunc();
			cout << "B::B(), this = " << this << endl;
		}
		virtual ~B()
		{
   
			myvirfunc();
			cout << "B::~B(), this = " << this << endl;
		}

	public:
		virtual void myvirfunc()
		{
   
			myvirfunc2();
			cout << "B::myvirfunc(), this = " << this << endl;
		}
		virtual void myvirfunc2()
		{
   
			cout << "B::myvirfunc2(), this = " << this << endl;
		}
	};

	class C : public B
	{
   
	public:
		C() : m_c(11)
		{
   
			myvirfunc(); // 调用一个虚函数
			cout << "C::C(), this = " << this << endl;
		}
		virtual ~C()
		{
   
			myvirfunc();
			cout << "C::~C(), this = " << this << endl;
		}

	public
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值