C++虚析构函数详解
例如下面的程序:
#include iostream using namespace std; class CShape //基类 public: ~CShape() { cout CShape::destrutor endl; } class CRectangle : public CShape //派生类 public: int w, h; //宽度和高度 ~CRectangle() { cout CRectangle::destrutor endl; } int main() CShape* p = new CRectangle; delete p; return 0; }
程序的输出结果如下:
CShape::destrutor
输出结果说明,delete p;只引发了 CShape 类的析构函数被调用,没有引发 CRectangle 类的析构函数被调用。这是因为该语句是静态联编的,编译器编译到此时,不可能知道此时 p 到底指向哪个类型的对象,它只根据 p 的类型是 CShape * 来决定应该调用 CShape 类的析构函数。
按理说,delete p;会导致一个 CRectangle 类的对象消亡,应该调用 CRectangle 类的析构函数才符合逻辑,否则有可能引发程序的问题。
例如,假设程序需要对 CRetangle 类的对象进行计数,如果此处不调用 CRetangle 类的析构函数,就会导致计数不正确。
再如,假设 CRectangle 类的对象在存续期间进行了动态内存分配,而释放内存的操作都是在析构函数中进行的,如果此处不调用 CRetangle 类的析构函数,就会导致被释放的对象中动态分配的内存以后再也没有机会回收。
综上所述,人们希望delete p;这样的语句能够聪明地根据 p 所指向的对象执行相应的析构函数。实际上,这也是多态。为了在这种情况下实现多态,C++ 规定,需要将基类的析构函数声明为虚函数,即虚析构函数。
改写上面程序中的 CShape 类,在析构函数前加 virtual 关键字,将其声明为虚函数:
class CShape{ public: virtual ~CShape() { cout CShape::destrutor endl; } };
则程序的输出变为:
CRectangle::destrutor
CShape::destrutor
说明 CRetangle 类的析构函数被调用了。实际上,派生类的析构函数会自动调用基类的析构函数。
只要基类的析构函数是虚函数,那么派生类的析构函数不论是否用virtual关键字声明,都自动成为虚析构函数。
一般来说,一个类如果定义了虚函数,则最好将析构函数也定义成虚函数。
析构函数可以是虚函数,但是构造函数不能是虚函数。
21566.html
chtml相关文章
- C++学习——memset函数详解
- c++基础篇之C++ 模板
- C++中的健壮指针和资源管理详解编程语言
- C/C++中可变参数函数的实现详解编程语言
- C++移动构造函数和移动赋值运算符详解
- C++字符串函数详解
- C++内联函数(C++ inline)详解
- C++ deque使用、创建及初始化详解
- C++ ?:条件运算符(三目运算符)用法详解
- C++类对象作为函数参数传递详解
- 二分搜索算法(C++详解版)
- C++ seekg函数用法详解
- C++ tellg和tellp函数用法详解
- 使用C++实现全排列算法的方法详解
- 基于C++list中erase与remove函数的使用详解
- 深入C++函数映射的使用详解
- C++中拷贝构造函数的总结详解