构造函数和析构函数调用虚函数会发生什么

写这个博客的原因是因为最近在面试的时候被问过好几次这个问题,但是却一直处于一种模棱两可的状态, 因此今天记录一下这个问题的一个理解已经代码实验的现象.

  • 构造函数调用虚函数

都知道虚函数是为了实现多态中的一个动态绑定过程. 而在进入派生类的构造函数之前,会先调用基类的构造函数.

话不多说,先看代码.

class base{
public:
    virtual void show(){
        cout << "this is base\n" << endl;
    }
    base(){
        show();
    }
};

class derived: public base{
public:
    virtual void show(){
        cout << "this is derived\n" << endl;
    }
    derived(){
        show();
    }
};
int main(){
    base* test_base = new derived;
    delete test_base;
    return 0;
}

执行结果为:
在这里插入图片描述
总结: 从语法上来说, 构造函数是可以调用虚函数的, 编译并不会有问题(面试被问会不会出现编译报错), 但是这么做起不到并起不到虚函数本身的动态绑定作用, 只会调用自身所在类的对应虚函数, 也就失去了这么做的意义. 同时从结果上也看出了派生类对象构造前先调用基类构造.

  • 析构函数调用虚函数
    同样的, 都知道析构函数的执行顺序是和构造函数相反的, 是一个从派生类到基类的一个顺序.
class base{
public:
    virtual void show(){
        cout << "this is base\n" << endl;
    }
    ~base(){
        show();
    }
};

class derived: public base{
public:
    virtual void show(){
        cout << "this is derived\n" << endl;
    }
    ~derived(){
        show();
    }
};
int main(){
	cout << "基类指针指向派生类对象的析构输出结果\n" << endl;
    base* test_base = new derived;
    delete test_base;
    cout << "派生类指针指向派生类对象的析构输出结果\n" << endl;
    derived* test_drived = new derived;
    delete test_drived;
    return 0;
}

在这里插入图片描述
从结果上看的话, 编译通过且输出了结果, 基类指针指向一个派生类对象, 在析构的时候其仍然是处于一个基类的状态, 因此会调用基类的show()函数, 而派生类指针指向派生类对象, 其是一个派生类因此会先调用派生类的析构函数,然后再调用基类的析构函数.

  • 总结
    析构函数和构造函数调用虚函数从语法上是没有问题的, 可以编译通过, 但是这种调用方式并没有什么意义, 不能体现虚函数的动态绑定特性.
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值