为多态基类声明一个虚析构函数(Effective C++_7)
来源:互联网 发布:淘宝极速退款五千额度 编辑:程序博客网 时间:2024/05/16 06:17
一、声明虚析构函数的原因
(1)先考虑没有声明虚析构函数的代码:
#include <iostream>using namespace std;class Base{public: Base(int x,int y):a(x),b(y){ cout<<"Base Construction"<<endl; } virtual void display()=0; ~Base(){ cout<<"Base Destuction"<<endl; }private: int a; int b;};class D1:public Base{public: D1(int x,int y,int z):Base(x,y),c(z){ cout<<"D1 Construction"<<endl; } void display(){ cout<<"D1 Class"<<endl; } ~D1(){ cout<<"D1 Destuction"<<endl; }private: int c;};class D2:public D1{public: D2(int x,int y,int z,int w):D1(x,y,z),d(w){ cout<<"D2 Construction"<<endl; } ~D2(){ cout<<"D2 Destuction"<<endl; } virtual void display(){ cout<<"D2 Class"<<endl; }private: int d;};int main(){ Base* p=new D1(1,2,3); p->display(); delete p; return 0;}
其结果是:
Base ConstructionD1 ConstructionD1 ClassBase Destuction请按任意键继续. . .
这里没有把析构函数声明为虚析构函数,那么,销毁对象时,只调用了基类的析构函数;假如,把基类的析构函数声明为虚析构函数,那么就会有下面的结果:
Base ConstructionD1 ConstructionD1 ClassD1 DestuctionBase Destuction请按任意键继续. .
当派生类的对象从内存中撤销时一般先调用派生类的析构函数,然后再调用基类的析构函数。但是,如果用new运算符建立了临时对象,若基类中有析构函数,并且定义了一个指向该基类的指针变量。在程序用带指针参数的delete运算符撤销对象时,会发生一个情况:系统会只执行基类的析构函数,而不执行派生类的析构函数;当声明为虚析构函数后,则会调用所有的析构函数,不会造成内存泄漏
二、何时声明为虚析构函数
(1)并不是所有c++类都应该将析构函数设置为virtual。只有具有virtual函数的多态基类(或者其它想当base class的类)才应该将析构函数设置为virtual,对于普通的类则无必要
因为虚函数的实现要求对象携带额外信息,也就是维护一个指向虚函数表的指针vfptr(virtual table pointer),vfptr指向虚函数表vtbl(virtual table)。当有虚函数时,声明一个对象时,对象的首地址会存储vfptr指针,而无虚函数时,则没有这样的指针;那么这会给对象带来多余的负担,所以对于非多态基类,没必要将析构函数声明为virtual以带来额外负担。
(2)纯虚析构函数:如果某个class只希望作为base class(不希望被实例化),但是又没有一个纯虚函数,而base class应该有一个virtual析构函数,那么此时就可以将析构函数设置为纯虚函数。必须为纯虚析构函数提供定义,否则会出现Link错误;
class Base{virtual ~Base()=0;}Base::~Base(){};
(3)如果一个类的不是设计作为基类来使用,或不是为了具备多态性,就不应该声明virtual析构函数
三、基类并非均是为了多态
(1)标准库中的STL容器和string类,不是设计作为基类使用的,它们均没有虚析构函数,不要继承它们
(2)比如Uncopyable的设计是为了明确拒绝赋值,而不是为了设计成多态,所以也不需要虚析构函数
参考:Effective C++ 3rd(侯捷译)
- 为多态基类声明一个虚析构函数(Effective C++_7)
- Effective C++ ——为多态基类声明虚析构函数
- Effective C++(十一):为需要动态分配内存的类声明一个复制构造函数和一个赋值操作符
- 《Effective C++》学习笔记条款07 为多态基类声明virtual析构函数
- Effective C++(7) 为多态基类声明virtual析构函数 or Not
- Effective C++——》条款7:为多态基类声明virtual析构函数 .
- Effective C++:条款07:为多态基类声明virtual析构函数
- [Effective C++]条款07 为多态基类声明virtual析构函数
- Effective c++(第三版) 条款7:为多态基类声明virtual析构函数
- Effective C++--条款07:为多态基类声明virtual析构函数
- 读书笔记《Effective C++》条款07:为多态基类声明virtual析构函数
- Effective C++读后感:为多态基类声明virtual析构函数
- effective c++ 为多态基类声明virtual析构函数
- Effective C++ 07:为多态基类声明virtual析构函数
- (原文)Effective C++条款7:为多态基类声明VIRTUAL析构函数
- effective C++ 读后感(七)为多态基类声明virtual析构函数
- effective c++ 条款07(为多态基类声明virtual析构函数)整理
- [翻译] Effective C++, 3rd Edition, Item 7: 在 polymorphic base classes(多态基类)中将 destructors(析构函数)声明为 virtual(虚拟)
- hdu 5418 (状态压缩)
- 四年程序员归零心态
- Android中的dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()
- 实体类(VO,DO,DTO)的划分
- c++题目——内存管理——待解决
- 为多态基类声明一个虚析构函数(Effective C++_7)
- laravrl Eloquent mark
- C C++ Intro - C语言中函数参数入栈的顺序
- 程序员眼中的女人
- 解决apache mina java.io.IOException: Connection timed out问题
- C# 托管资源和非托管资源
- Android : onInterceptTouchEvent
- Java 垃圾回收机制概念梳理
- 对C++中字符串常量的理解