有关delete操作符
#include<iostream>class Base1
{
public:
virtual ~Base1(){}
};
class Base2
{
public:
virtual void f()=0;
// virtual ~Base2(){};
};
class Derive:public Base1,public Base2
{
public:
void f(){std::cout<<"f\n";}
~Derive(){std::cout<<"Derive dtor\n";}
};
void func(Base2* p)
{
p->f();
}
int main(int , char**)
{
Derive *p = new Derive;
Base1 *pb1=p;
Base2 *pb2=p;
func(p);
delete p;
//delete pb1;
//delete pb2;
}
此代码通过修改base2的虚dtor 和 main中的delete pb2 ,会导致crash。
所谓的delete分为两步,runtime在遇到一个delete的时候,理论上会调用一个叫做deleteoperator的东西,这个东西会先调用dtor,然后调用operator delete来释放内存。我们能够重载的是operatordelete,而delete operator是无法重载的。对于operatordelete来说,它接受一个void*为参数,它只负责释放内存。那么,按照你的layout,pb1和d指向的内存地址肯定是不一样的,由于Base1有大小,pb2会有一个偏移。因此,对于operator delete来说,如果你传给它pb2,它就直接over了。那么,delete operator怎么可以知道应该怎样传递正确地传递地址过去呢?这是因为,deleteoperator有点类似于virtual的。要实现这个virtual特性的先决条件就是,你的dtor必须是virtual的。这就可以解释为什么你把virtual注释了,就会over。
<div style="text-align: left;"><div class="c"><ol><li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;">static void* operator new(size_t size){
页:
[1]