cpp_destructor_virtual - ShenYj/ShenYj.github.io GitHub Wiki
- 如果存在父类指针指向子类对象的情况,应该将析构函数声明为虚函数(虚析构函数)
-
delete父类指针时,才会调用子类的析构函数,保证析构的完整性
struct Animal { void speak() { cout << "Animal::speak()" << endl; } void run() { cout << "Animal::run()" << endl; } ~Animal() { cout << "Animal::~Animal()" << endl; } }; struct Cat: Animal { void speak() { cout << "Cat::speak()" << endl; } void run() { cout << "Cat::run()" << endl; } ~Cat() { cout << "Cat::~Cat()" << endl; } }; int main() { Animal *cat = new Cat(); cat->speak(); /// 打印结果 Animal::speak() /// 回收堆空间内存, 会调用析构函数 delete cat; /// 打印结果 Animal::~Animal() /// 完整打印结果 /// Animal::Animal() /// Car::Cat() /// Animal::speak() /// Animal::~Animal() }
通过log观察, Cat的析构没有调用; 因为没有虚函数,不存在虚表, delete的时候就根据左侧 Animal 的类型去执行析构
-
将析构声明为虚函数
struct Animal { void speak() { cout << "Animal::speak()" << endl; } void run() { cout << "Animal::run()" << endl; } virtual ~Animal() { cout << "Animal::~Animal()" << endl; } }; struct Cat: Animal { void speak() { cout << "Cat::speak()" << endl; } void run() { cout << "Cat::run()" << endl; } ~Cat() { cout << "Cat::~Cat()" << endl; } }; int main() { Animal *cat = new Cat(); cat->speak(); delete cat; /// 完整打印结果 /// Animal::Animal() /// Car::Cat() /// Animal::speak() /// Cat::~Cat() /// Animal::~Animal() }
加上虚函数,成功的调用了 Cat 和 Animal 的析构函数
-
-