zoukankan      html  css  js  c++  java
  • 虚析构和纯虚析构

    虚析构的诞生原因:
    当父类指针指向子类的时候,如果父类不写成虚析构,子类的析构函数调不了,在堆区开辟的内存无法释放。

     如下代码红色部分不是虚析构。

     1 class Animal
     2 {
     3 public:
     4     Animal() {
     5         cout << "Animal的构造函数的调用" << endl;
     6     }
     7     virtual void speak() = 0;
     8     // 利用虚析构可以解决父类指针释放子类对象不干净的问题
     9        ~Animal() {
    10         cout << "Animal的析构函数的调用" << endl;
    11     }
    12     /*virtual ~Animal() = 0;*/
    13 };
    14 
    15 
    16 //Animal:: ~Animal() {
    17 //
    18 //    cout << "Animal的纯虚析构函数的调用" << endl;
    19 //
    20 //}
    21 
    22 
    23 
    24 
    25 class Cat :public Animal
    26 {
    27 public:
    28     Cat(string name) {
    29         cout << "Cat的构造函数的调用" << endl;
    30         m_Name = new string(name);
    31 
    32 
    33     }
    34     virtual void speak() {
    35         cout << *m_Name << "小猫在说话" << endl;
    36     }
    37     ~Cat() {
    38         if (m_Name != NULL) {
    39             cout << "Cat的析构函数的调用" << endl;
    40             delete m_Name;
    41             m_Name = NULL;
    42         }
    43     }
    44 
    45     string * m_Name;
    46 };
    47 
    48 void  test01() {
    49     Animal * animal = new Cat("TOM");
    50     animal->speak();
    51     delete animal;
    52 }
    53 
    54 
    55 int main() {
    56     test01();
    57 
    58 
    59     return 0;
    60 }

    编译结果:

    可以看到子类cat的析构函数并未调用。

    改进后代码:

    #include<iostream>
    using namespace std;
    #include<string>
    class Animal
    {
    public:
        Animal() {
            cout << "Animal的构造函数的调用" << endl;
        }
        virtual void speak() = 0;
        // 利用虚析构可以解决父类指针释放子类对象不干净的问题
        virtual ~Animal() {
            cout << "Animal的析构函数的调用" << endl;
        }
       
    };
    class Cat :public Animal
    {
    public:
        Cat(string name) {
            cout << "Cat的构造函数的调用" << endl;
            m_Name = new string(name);
        }
        virtual void speak() {
            cout << *m_Name << "小猫在说话" << endl;
        }
        ~Cat() {
            if (m_Name != NULL) {
                cout << "Cat的析构函数的调用" << endl;
                delete m_Name;
                m_Name = NULL;
            }
        }
    
        string * m_Name;
    };
    
    void  test01() {
        Animal * animal = new Cat("TOM");
        animal->speak();
        delete animal;
    }
    
    
    int main() {
        test01();
    
    
        return 0;
    }

    运行结果:

    父类可能也有一些数据开辟到堆区,所以纯虚析构也是需要 函数体的。有了纯虚析构之后,这个类也属于抽象类,无法实例化对象。

  • 相关阅读:
    CentOS7和Ubuntu18.10下运行Qt Creator出现cannot find -lGL的问题的解决方案
    C++中使用CMake编译管理项目
    C++ std::isnan等函数的使用
    七个开源的 Spring Boot 前后端分离项目,一定要收藏!
    基于Select模型的Windows TCP服务端和客户端程序示例
    简单的C++11线程池实现
    Windows下FFMEPG编译
    MIMO431学习笔记目录
    golang调用海康sdk
    GRPC-go版本
  • 原文地址:https://www.cnblogs.com/YXBLOGXYY/p/14334979.html
Copyright © 2011-2022 走看看