effective c++ 04 多态实现03(不要在构造函数和析构函数中调用虚函数)

标题不要在构造函数和析构函数中执行虚函数

在这里插入图片描述
今天的主题我用一句话总结:如果你在基类的构造函数或者析构函数中调用虚函数,那么这个虚函数会被当做普通的成员函数。
1.对于构造函数:
子类在执行构造函数之前会先执行父类的构造函数,此时子类的专属部分还未被初始化,所以面对那些专属部分编译器就把它视而不见,也就是子类在构造函数之前编译器将子类(派生类)当做成了父类(基类)。
2.对于析构函数:
析构函数的执行顺序是先执行派生类的析构函数然后再执行基类的析构函数。当执行基类析构函数的时候,派生类的析构函数已经执行完毕,所以此时编译器就把派生类的成员当做未定义,也就是说当进入基类的析构函数中时,将派生类当做一个基类对象。
接下来看个例子:

class A{
public:
	A()
	{
		cout << "A:print()*****:";
		print();
	}
	virtual void print()
	{
		cout << "I am A\n";

	}
	~A()
	{
		cout << "~A:print()*****:";
		print();
	}
};

class B:public A{
public:

	B()
	{
		cout << "B:print()*****:";
		print();
	}
	virtual void print()
	{
		cout << "I am B\n";

	}
	~B()
	{
		cout << "~B:print()*****:";
		print();
	}
};

void playxx()
{
	B b;

}

int main()
{
	playxx();
	
	system("pause");
}

结果:
By Ty
从结果可以看出来,在基类执行析构函数的时候,只调用了基类的虚函数,并没有调用子类的析构函数。其实总结下来也就是:在派生类对象的基类部分构造期间,就把派生类对象视为一个基类对象,这时调用的虚函数版本,就是基类的版本。
构造函数的调用顺序是从基类到派生类,逐层构造。在构造的过程中,vptr被指向本层的vtable。而虚函数的行为依赖于vptr。因此,在本层构造函数中,编译器无法获知派生类的任何信息,因此无法形成正确的vtable访问。Vtable在上节讲过,它是存储在一段连续的内存空间中,因为派生类构造函数还没有执行,所有没有空间,从而也就没有生成vtable.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发如雪-ty

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值