多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用子类的析构代码。
解决方式:将父类中的析构函数改为虚函数或純虚函数。
虚析构函数和純虚函数的共性:
虚析构和析构函数的区别:
#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; }
输出:
原文:https://www.cnblogs.com/xiximayou/p/12102379.html