绝不在构造/析构函数中使用虚函数

本文探讨了在构造函数中直接调用虚函数可能导致的行为不确定性问题,并提供了解决方案,即通过传递参数的方式避免在构造期间调用虚函数。
假设有一个class继承体系,在构造函数中调用了一个虚函数,如:
 
   
  1. class A{
  2. public:
  3. A();
  4. virtual void dosomething();
  5. }
  6. A::A()
  7. {
  8. dosomething();
  9. }
 
    
  1. class B:public A{
  2. public:
  3. virtual void dosomething();
  4. }
然后执行如下语句
 
    
  1. B b;
无疑的,会有B的构造函数被调用,但首先A的构造函数会被调用,因为基类的构造函数总是先于派生类的构造函数被调用。
而此时在A的构造函数中被调用的dosomething()函数是A的版本,而不是被B覆盖的版本。因为在A的构造期间,b还是个基类对象,
不可能访问到B覆盖的版本,否则会导致不明确行为。比如B的dosomething()可能访问了某个派生成员,而在A的构造期间,那些派生成员
都还没被构造出来,这样就会导致不明确行为。

相同道理也适用于析构函数,一旦派生类析构函数开始执行,对象内的派生类成员变量就呈现为定义值,C++视他们不存在,进入基类虚构函数后对象就变成一个基类对象。

解决的办法是将那个函数声明为非虚的但需要参数。
由于你无法使用虚函数从基类向下调用,在构造期间,可以由派生类将必要的构造信息向上传递至基类构造函数加以弥补。




转载于:https://www.cnblogs.com/Lighters-c/p/6080625.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值