何为C++对象模型?
C++对象模型可以概括为以下2部分:
1、语言中直接支持面向对象程序设计的部分;
2、对于各种支持的底层实现机制。
语言中直接支持面向对象程序设计的部分,如构造函数、析构函数、虚函数、继承(单继承、多继承、虚继承)、多态等等。本文重点介绍底层实现机制。
在C语言中,“数据”和“处理数据的操作(函数)”是分开声明的,也就是说,语言本身并没有支持“数据和函数”之间的关联性。在C++中,通过抽象数据类型(Abstract Data Type,ADT),在类中定义数据和函数,来实现数据和函数直接的绑定。概括来说,在C++类中有两种数据成员:static,nonstatic;三种成员函数:static、nonstatic、virtual。
为什么析构函数设为虚函数是必要的
析构函数应当都是虚函数,除非明确该类不做基类(不被其他类继承)。基类的析构函数声明为虚函数,这样做是为了确保释放派生对象时,按照正确的顺序调用析构函数。
从前面介绍的C++对象模型可以知道,如果析构函数不定义为虚函数,那么派生类就不会重写基类的析构函数,在有多态行为的时候,派生类的析构函数不会被调用到(有内存泄漏的风险!)。
例如,通过new一个派生类对象,赋给基类指针,然后delete基类指针。
void test_vitual_destructor()
{
Base *p = new Derived();
delete p;
}
如果基类的析构函数不是析构函数:
注意,缺少了派生类的析构函数调用。把析构函数声明为虚函数,调用就正常了:
相关资料
[1] 深度探索C++对象模型,侯捷
[2] 测试代码下载:https://github.com/saylorzhu/CppObjectDataModelTestCode
[3] 关于虚函数的实现原理也可以参考关于虚函数的那些事儿