Item 7:将多态基类的析构函数声明为虚函数 Effective C++笔记
2015-08-24 13:18
344 查看
虚析构函数
Item 7: Declare destructors virtual in polymorphic base classes析构函数声明为虚函数恐怕是面试中最常见的问题之一。目的在于以基类指针调用析构函数时能够正确地析构子类部分的内存。 否则子类部分的内存将会泄漏,正确的用法如下:
// 基类 class TimeKeeper{ public: virtual ~TimeKeeper(); ... }; TimeKeeper *ptk = getTimeKeeper(): // 可能返回任何一种子类 ... delete ptk;
值得一提的是虚函数表指针的内存占用问题,我们知道所有存在虚方法的对象中都会存有一个虚函数表指针
vptr,
用来在运行时定位虚函数。同时,每个存在虚方法的类也会对应一个虚函数列表的指针
vtbl。
函数调用时会在
vtbl指向的虚函数表中寻找
vptr指向的那个函数。
为了准确地描述
vptr的大小,先来了解一下对象的
sizeof计算方式,以及字节对齐问题:
编译器:gcc version 5.1.0,目标平台:x86_64-apple-darwin14.3.0
空对象大小为1
没有任何成员的对象也需要有地址,否则怎么定位它呢?所以编译器会给它一字节的大小:class C0{}; sizeof(C0); // 1 class C1{ char i; }; sizeof(C1); // 1
只有一个
char成员的对象大小也是1
字节对齐
整个对象的大小会按照最大的成员进行字节对齐。例如:class C2{ char i, j; }; sizeof(C2); // 2 class C3{ char i, j; int k; }; sizeof(C3); // 8
因为
int大小是4,两个
char大小是2,故总的大小以4为基对齐,大小为4*2
= 8。
虚函数表指针
class C4{ char i; virtual void func(); }; sizeof(C4); // 16
因为我的Target是64位平台,故
vptr的大小为8,
char大小为1,故总的大小以8为基对齐,大小为8*2
= 16。 虚函数指针不仅使得对象更加占用内存空间,同时会造成可移植性问题。 问题很明显:一个包含
vptr的C++对象传递给Fortran时,由于Fortran中没有
vptr的概念,
因此需要重新计算对象大小,然而
vptr的大小是平台相关的。。。
封闭类
包含对象成员的类称为封闭类,封闭类以对象成员中最大的基本数据类型的长度进行字节对齐。例如:class C5{ C4 c4; char i; }; sizeof(C5); // 24
C4和C5中最大的基本数据类型是
void*(
vptr的类型),其大小为8,故以8为基对齐的结果是8*3
= 24。
除非注明,本博客文章均为原创,转载请以链接形式标明本文地址: http://harttle.com/2015/07/24/effective-cpp-7.html
相关文章推荐
- Item 6:禁用那些不需要的缺省方法 Effective C++笔记
- C++对象内存布局
- Item 5:那些被C++默默地声明和调用的函数 Effective C++笔记
- 阿里巴巴2016校园招聘在线笔试(C/C++)附加题 第二题
- Machine Schedule
- 《算法导论》中求最大子数组的C++实现
- C++ Primer 5e chapter 15.1
- [C++]Reverse Integer整数翻转
- c++程序的内存布局
- C++ STL
- C++ Tips: 在控制台中显示中文
- 详解C语言中index()函数和rindex()函数的用法
- 在C语言中比较两个字符串是否相等的方法
- 【C++】不要在构造函数或析构函数内调用虚函数
- 在C++代码中调用L脚本语言
- [C++]Excel Sheet Column Title
- C语言中查找字符在字符串中出现的位置的方法
- C语言中strspn()函数和strcspn()函数的对比使用
- C++ 初始化列表
- vc++6.0 字节运算