虚析构函数问题
引用标准中原文: 一条有用的方针,是任何基类的析构函数必须为公开且虚, 或受保护且非虚。
虚析构这个概念被设计出来就是为了解决基类指针指向派生类实例的析构问题,当一个基类指针指向派生类实例然后进行delete该指针时,只会执行基类析构函数而派生类的析构函数不会被执行,这将导致派生类构造的资源不会被正确释放,造成内存泄漏。如下示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <iostream>
struct Base { Base() { std::cout << "Base Construct!" << std::endl; } ~Base() { std::cout << "Base Deconstruct!" << std::endl; } };
struct Derived : public Base { Derived() { std::cout << "Derived Construct!" << std::endl; } ~Derived() { std::cout << "Derived Deconstruct!" << std::endl; } };
int main() { { Base* BasePtr = new Derived; delete BasePtr; } system("pause"); }
|
运行结果:
可以看到派生类没有被析构,如要解决该问题在基类析构函数处加上virtual关键字即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <iostream>
struct Base { Base() { std::cout << "Base Construct!" << std::endl; } virtual ~Base() { std::cout << "Base Deconstruct!" << std::endl; } };
struct Derived : public Base { Derived() { std::cout << "Derived Construct!" << std::endl; } ~Derived() { std::cout << "Derived Deconstruct!" << std::endl; } };
int main() { { Base* BasePtr = new Derived; delete BasePtr; } system("pause"); }
|
运行结果: