zoukankan      html  css  js  c++  java
  • C++ 虚析构(virtual destructor)原理

    注意:本文仅为个人理解,可能有误!

    先看一段代码:

    #include <iostream>
    using namespace std;
    
    class CBase{
    public:
        CBase()
        {
            cout<<"CBase construct ... "<<endl;
        }
        virtual ~CBase()
        {
            cout<<"CBase destructor ... "<<endl;
        }
    };
    
    class CSon : public CBase{
    public:
        CSon(){
            cout<<"CSon construct ... "<<endl;
        }
        ~CSon(){
            cout<<"CSon destructor ... "<<endl;
        }
    };
    
    void test()
    {
        CBase* pObj = new CSon();
        delete pObj;
    }
    
    int main(int argc,char* argv[])
    {
        test();
        return 0;
    }

    上面这段代码,输出:

    CBase construct ...
    CSon construct ...
    CSon destructor ...
    CBase destructor ...

    大家都能理解,而将virtual ~CBase() 的virtual 去掉, 将输出:

    CBase construct ...
    CSon construct ...
    CBase destructor ...

    大家将看到,子类的析构函数没有被调用。

    那为什么加了virtual就会调用子类的析构函数呢?这是本文的主题

    首先要理解几个概念:

    0,在没有加virtual的时候,这个继承体系没有任何虚函数,所以CSon,CBase均不含虚函数表。

    1,子类构造函数/析构函数会自动调用父类的构造/析构函数(编译期决定);

    2,编译期的常识:

    CBase* pObj = new CSon(); 

    这句相当于

    CSon* pTmp = new CSon();

    CBase* pObj = (CBase*)pTmp; 

    前一句中编译器是直接调用CSon::CSon()返回位pTmp,pTmp赋值给pObj。因而生成的pObj实际上是CSon对象,但pObj的类型被记录为CBase类型。

    delete pObj;  

    delete时编译器只知道这个pObj是CBase类型 。

    情况一,在CBase的析构函数为非virtual时:

    编译器在编译“delete pObj;” 时根据pObj的类型是CBase调用CBase::~CBase(),不会调用子类析构函数。

    情况二,在CBase的析构函数为virtual时:

    此时继承体系中有一个虚函数表,这个时候,编译器就不会直接调用CBase::~CBase(),而是调用call pObj->pvtable-> vtable[0],又pObj这个对象实际上是CSon对象,所以调用流程如下:

    delete pObj; –> call pObj->pvtable-> vtable[0] –> CSon::~CSon()

    而在CSon::~CSon中会自动递归调用父类的析构函数,所以全部资源释放完成。

    关于动态绑定部分,可以参见如下两张图:

    1,CBase初始化完毕:

    base

    2,CSon初始化完毕:

    son

  • 相关阅读:
    Linux的中文输入法Fcitx-国货精品
    Linux内核编译与安装[转]
    Linux内核编译与安装[转]
    修改镜像地址加快Ubuntu更新速度
    修改镜像地址加快Ubuntu更新速度
    OSX操作技巧:快速锁定系统(类似Windows+L)
    NDK编程入门笔记[转]
    NDK编程入门笔记[转]
    内置函数图形分类
    函数的定义
  • 原文地址:https://www.cnblogs.com/xylc/p/3586892.html
Copyright © 2011-2022 走看看