C++的虚析构函数
2012-02-03 23:21
246 查看
class A { public: A(){} virtual ~A(){} //这里如果不用虚函数那么下面 delete p;就只会调用 ~A(),显然造成了内存的泄漏,m_data的空间泄漏了 }; class B : public A { public: char* m_data; B() { m_data = new char[100]; } ~B() { delete m_data; } }; int main(int argc, char **argv) { A *p = new B; delete p; //先调用析构函数 再free空间 return 0; }
虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并用基类的指针删除派生类对象。如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个虚函数表,使得对象的体积翻倍,还有可能降低其可移植性。所以基本的一条是:无故的声明虚析构函数和永远不去声明一样是错误的。实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。
#include <stdio.h> class Base { public: virtual ~Base() = 0; }; Base::~Base() { printf("..\n"); } //这个却不能省 class A : public Base { }; int main() { A a; return 0; }
这个类有一个纯虚函数,所以它是抽象的,而且它有一个虚析构函数,所以不会产生析构函数问题。但这里还有一件事:必须提供纯虚析构函数的定义:Base::~Base()
{ printf("..\n"); }必须得定义。这个定义是必需的,因为虚析构函数工作的方式是:最底层的派生类的析构函数最先被调用,然后各个基类的析构函数被调用。这就是说,即使是抽象类,编译器也要产生对~Base的调用,所以要保证为它提供函数体。如果不这么做,链接器就会检测出来,最后还是得回去把它添上。注意:如果声明虚析构函数为inline,将会避免调用它们时产生的开销,但编译器还是必然会在什么地方产生一个此函数的拷贝。
相关文章推荐
- C++继承中的虚析构函数
- C++ 虚析构函数 纯虚析构函数 虚构造函数
- 为什么析构函数总是虚函数?如果这是必要的,那么为什么C++不把虚析构函数直接作为默认值?
- (C++)虚析构函数
- C++的虚析构函数
- c++虚析构函数
- C++虚析构函数及纯虚析构函数
- C++继承中构造函数、析构函数调用顺序及虚析构函数
- c++面向接口编程,虚函数,虚析构函数
- C++虚析构函数的作用
- c++虚析构函数
- C++多态为什么要定义虚析构函数
- C++继承中的虚析构函数
- C++学习笔记-----存在多态调用时,为基类定义虚析构函数
- C++ 为什么要虚析构函数
- C++中的虚析构函数,C++陷阱
- C++之虚析构函数
- C++虚析构函数
- C++学习笔记 -- 虚析构函数与纯虚析构函数
- c++ 虚析构函数