虚析构函数? vptr? 指针偏移?多态数组? delete 基类指针 内存泄漏?崩溃?

本文探讨了C++中虚函数、多态数组以及使用基类指针删除对象时可能遇到的问题,包括vptr的继承、虚函数调用规则、析构函数的虚性对内存管理的影响,特别是析构函数不声明为虚函数可能导致的内存泄漏和程序崩溃。文章通过实例解析了标准规定的五条基本规则,并分析了不同编译器的实现差异,强调了遵循最佳实践以避免undefined behavior的重要性。
摘要由CSDN通过智能技术生成

五条基本规则:


1、如果基类已经插入了vptr, 则派生类将继承和重用该vptr。vptr(一般在对象内存模型的顶部)必须随着对象类型的变化而不断地改变它的指向,以保证其值和当前对象的实际类型是一致的。


2、在遇到通过基类指针或引用调用虚函数的语句时,首先根据指针或引用的静态类型来判断所调函数是否属于该class或者它的某个public 基类,如果

属于再进行调用语句的改写:

 C++ Code 
1
(*(p->_vptr[slotNum]))(p, arg-list);

其中p是基类指针,vptr是p指向的对象的隐含指针,而slotNum 就是调用的虚函数指针在vtable 的编号,这个数组元素的索引号在编译时就确定下来,

并且不会随着派生层的增加而改变。如果不属于,则直接调用指针或引用的静态类型对应的函数,如果此函数不存在,则编译出错。


3、C++标准规定对对象取地址将始终为对应类型的首地址,这样的话如果试图取基类类型的地址,将取到的则是基类部分的首地址。我们常用的编译器,如vc++、g++等都是用的尾部追加成员的方式实现的继承(前置基类的实现方式),在最好的情况下可以做到指针不偏移;另一些编译器(比如适用于某些嵌入式设备的编译器)是采用后置基类的实现方式,取基类指针一定是偏移的。


4、delete[]  的实现包含指针的算术运算,并且需要依次调用每个指针指向的元素的析构函数,然后释放整个数组元素的内存。


5、 在类继承机制中,构造函数和析构函数具有一种特别机制叫 “层链式调用通知” 《 C++编程思想 》

C++标准规定:基类的析构函数必须声明为virtual, 如果你不声明,那么"层链式调用通知"这样的机制是没法构建起来.从而就导致了基类的析构函数被调用了,而派生类的析构函数没有调用这个问题发生.


如下面的例子:

 C++ Code 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值