c++之虚析构和純虚析构

时间:2022-07-23
本文章向大家介绍c++之虚析构和純虚析构,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用子类的析构代码。

解决方式:将父类中的析构函数改为虚函数或純虚函数。

虚析构函数和純虚函数的共性:

  • 可以解决父类指针释放子类对象;
  • 都需要有具体的函数实现;

虚析构和析构函数的区别:

  • 如果是純虚析构,该类属于抽象类,无法实例化对象。
#include<iostream>
using namespace std;

class Animal {
public:
    Animal() {
        cout << "Animal的构造函数调用" << endl;
    }
    /*virtual ~Animal() {
        cout << "Animal的析构函数调用" << endl;
    }*/
    //对于纯虚析构,既要有声明,也需要在类外进行实现,
    //純虚函数是不需要实现的,只需要声明
    virtual ~Animal() = 0;
    virtual void speak() = 0;
};
Animal::~Animal() {
    cout << "Animal的析构函数调用" << endl;
}
class Cat :public Animal {
public:
    string name;
    Cat(string name) {
        cout << "Cat的Cat(string name)构造函数调用" << endl;
        this->name = name;
    }
    ~Cat() {
        cout << "Cat的析构函数调用" << endl;
        this->name = name;
    }
    void speak() {
        cout << "喵喵喵" << endl;
    }
};
class Dog :public Animal {
public:
    string name;
    Dog(string name) {
        cout << "Dog的Dog(string name)构造函数调用" << endl;
        this->name = name;
    }
    ~Dog() {
        cout << "Dog的析构函数调用" << endl;
        this->name = name;
    }
    void speak() {
        cout << "汪汪汪" << endl;
    }
};

//这里必须传入地址
//父类的引用指向子类的对象,实现动态多态
void doSpeak()
{
    Animal* animal = new Cat("tom");
    //父类指针在析构时,不会调用子类中的析构函数。导致了子类中有堆区属性,出现内存泄漏;
    //解决方法,将父类析构函数声明为virtual
    animal->speak();
    delete animal;
    cout << "-----------------------" << endl;
    animal = new Dog("jack");
    animal->speak();
    delete animal;
}

int main() {
    doSpeak();
    system("pause");
    return 0;
}

输出: