C++中最好不要在构造函数和析构函数中调用虚函数

1.最好不要在基类和派生类的构造和析构函数中调用虚函数,不会出现多态性
实例如下:

    #include "iostream"

    using namespace std;


    class Base{
        public:
            Base(){
                cout << "Base::Base()\n";
                fun();
            }
            virtual ~Base(){
                cout << "Base::Base()\n";
                fun();
            }
            virtual void fun(){
                cout << "Base::fun() virtual\n";
            }
    };

    // 派生类
    class Derive: public Base{
        public:
            Derive(){
                cout << "Derive::Derive()\n";
                fun();
            }
            ~Derive(){
                cout << "Derive::Derive()\n";
                fun();
            }
            virtual void fun(){
                cout << "Derive::fun() virtual\n";
            }
    };

    int main(){
        Base *b = new Base();
        delete b;
        cout << "-----------------------------------\n";
        Derive *d = new Derive();
        delete d;
        cout << "-----------------------------------\n";
        Base *bd = new Derive();  // 基类Base的指针bd指向的是派生类Derive的对象
        delete bd;
        return 0;
    }


解释: 第一段代码不加说明,第二段代码Derive *d = new Derive();先调用类的构造函数,这个构造函数是基类Base的fun()函数,因为此时派生类Derive还不存在,然后才构造派生类Derive。析构时,先析构派生类Derive,并调用派生类的fun()函数,再析构基类。第三段代码Base *bd = new Derive();基类Base的指针bd指向派生类对象。构造时,先调用基类Base的构造函数,此时构函数中调用基类中的fun()函数,此时虚函数的动态绑定机制并没有会生效,这是因为此时的派生类还不存在。析构时,先析构派生类,派生类中的fun()函数调用的是自己的fun(),然后析构基类Base,基类析构函数中的fun()调用的是基类Base自己的fun()函数,这里虚函数的动态绑定机制也没有生效,因为此时派生类已经不存在了。
2.总结
不要在构造函数中调用虚函数的原因:因为父类对象会在子类之前进行构造,此时子类部分的数据成员还未初始化, 因此调用子类的虚函数是不安全的,故而C++不会进行动态联编。
不要在析构函数中调用虚函数的原因:析构函数是用来销毁一个对象的,在销毁一个对象时,先调用子类的析构函数,然后再调用基类的析构函数。所以在调用基类的析构函数时,派生类对象的数据成员已经“销毁”,这个时再调用子类的虚函数已经没有意义了。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值