• 虚析构函数使用


    说到虚析构函数,我们先来看看析构函数的作用:在删除指向动态分配对象的指针时,需要运行析构函数在释放对象的内存之前清除对象。

    在处理继承层次的对象时,指针的静态类型可能与被删除对象的动态类型不符,可能会删除实际指向派生类对象的基类类型指针。

    怎么理解这句话呢,在有继承的时候,如果我们删除一个指向子类的基类类型的指针F,也就是说指针F的类型是基类,但这个指针指向子类。这个时候如果要删除这个指针,调用的应该是基类的析构函数。如下代码:

     1 //base.h
     2 
     3 #include <iostream>
     4 
     5 using namespace std;
     6 
     7 class A{
     8 public:
     9     A() {
    10         cout << "A" << endl;
    11     }
    12     ~A() {
    13         cout << "~A" << endl;
    14     }
    15 };
    16 
    17 class B: public A{
    18 public:
    19     B() {
    20         cout << "B" << endl;
    21     }
    22     ~B() {
    23         cout << "~B" << endl;
    24     }
    25 };
     1 //main.cpp
     2 
     3 #include"base.h" 
     4 #include<iostream>
     5 
     6 using namespace std;
     7 
     8 int main(int argc,char*argv[])
     9 { 
    10     A* te = new B;
    11     delete te;
    12     return 0;
    13 } 

    运行结果是:

    A
    B
    ~A
    请按任意键继续. . .

    但是实际上对象是B类型的,也就是说应该调用B的析构函数才对。

    我们来考虑一种情况,当类B中有一个新的函数,改函数开出了一个内存空间,如new 出了一个对象。那么在删除指针F的时候,我们调用的是基类的析构函数,但基类的析构函数没有释放类B中的那个函数开出的空间,就会造成内存泄漏。为了解决这个问题,我们必须另基类的析构函数为虚函数。

    如果基类的析构函数为虚函数,那么通过指针调用时,运行哪个析构函数将因指针所指的对象类型的不同而不同。

    如下:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 class A{
     6 public:
     7     A() {
     8         cout << "A" << endl;
     9     }
    10     virtual ~A() {
    11         cout << "~A" << endl;
    12     }
    13 };
    14 
    15 class B: public A{
    16 public:
    17     B() {
    18         cout << "B" << endl;
    19     }
    20     ~B() {
    21         cout << "~B" << endl;
    22     }
    23 };

    运行结果:

    A
    B
    ~B
    ~A
    请按任意键继续. . .

    像其他虚函数一样,析构函数的虚函数性质都将继承。因此,如果层次中根类的析构函数为虚函数,那么派生类的析构函数也将是虚函数,无论派生类显式定义析构函数还是使用合成析构函数,派生类的析构函数都是虚函数。

    因此,为了程序的正常运行,就算析构函数没有工作要做,继承层次的根类也应该定义一个虚析构函数。

  • 相关阅读:
    html5标签---不常用新标签的整理
    拖拽demo--兼容--全局捕获
    Linux now!--网络配置
    windows下 memcached 和 redis 服务器安装
    MySQL5.6安装步骤(windows7/8_64位)
    zend 环境
    mysql自增id超大问题查询
    烦人的运营后台导出大批量数据
    kafka环境搭建和使用(python API)
    分布式系统中zookeeper实现配置管理+集群管理
  • 原文地址:https://www.cnblogs.com/xiezhw3/p/3545220.html
Copyright © 2020-2023  润新知