虚析构和纯虚析构

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

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

 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;
}

运行结果:

 

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

posted on 2021-01-27 14:49  Love&Share  阅读(99)  评论(0编辑  收藏  举报

导航