C++中的virtual析构函数

当一个类被继承时,在它的子类析构的过程中会有一个析构链\
调用子类的析构函数\
销毁类对象的数据成员\
调用父类的析构函数\

1.下面看一个在父类的析构函数没有被声明为virtual的时的测试程序以及输出结果。
不保证下面的代码在拷贝后一定能运行!

#include <iostream>

using namespace std;

class parent{
public:
    ~parent(){ cout << "~parent" << endl; }
};
class child : public parent{
public:
    ~child(){ cout << "~child" << endl; }
};

void testPointer(){
    parent *p = new child();

    delete p;
}
int _tmain(int argc, _TCHAR* argv[])
{
    cout << "_____________________________________" << endl;
    testPointer();
    cout << "_____________________________________" << endl;
    system("pause");
    return 0;
}

输出结果:
这里写图片描述
delete时只调用了父类的析构函数,没有电泳调用子类的析构函数。\
这就可能在我们程序运行过程中导致内存泄漏,以及其他根据业务不\
同的错误。

2.当父类的析构函数被virtual修饰时的测试代码如下:

#include <iostream>

using namespace std;

class parent{
public:
    virtual ~parent(){ cout << "~parent" << endl; }
};
class child : public parent{
public:
    virtual ~child(){ cout << "~child" << endl; }
};

void testPointer(){
    parent *p = new child();

    delete p;
}
int _tmain(int argc, _TCHAR* argv[])
{
    cout << "_____________________________________" << endl;
    testPointer();
    cout << "_____________________________________" << endl;
    system("pause");
    return 0;
}

输出结果如下:
这里写图片描述
通过结果我们可以看出来调用顺序符合我们开始写的析构链。

这里的函数调用必须有个动态绑定,要实现这种动态绑定必须满足两个条件:

父类指针在进行析构时,函数调用必须有个动态绑定,要实现这种动态绑定\
必须满足两个条件:
(1). 只有指定为虚函数的成员函数才能进行动态绑定.
(2). 必须通过基类类型的指针或者引用进行函数调用.

产生这种不同的主要原因是,当父类析构函数没有被virtual修饰时,\
也就是说在delete父类指针时不会对函数进行动态绑定,而是根据父\
类指针的静态类型(声明时类型),进行函数调用,这里自然先调用\
父类的析构函数,根据我们的析构链可以知道:父类析构函数不会调\
用子类析构函数,因此我们测试程序一的只调用了父类析构函数。当\
父类函数被virtual修饰时,这里进行函数调用时会进行动态绑定,也\
就是调用指针实际指向的对象的方法,由于父类指针指向了子类对象\
这里自然就调用到了子类的析构函数,接下来就按照我们的析构链执\
行了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值