回复: 为什么会crash? 其实所谓的delete分为两步,runtime在遇到一个delete的时候,理论上会调用一个叫做delete operator的东西,这个东西会先调用dtor,然后调用operator delete来释放内存。我们能够重载的是operator delete,而delete operator是无法重载的。
对于operator delete来说,它接受一个void*为参数,它只负责释放内存。那么,按照你的layout,pb1和d指向的内存地址肯定是不一样的,由于Base1有大小,pb2会有一个偏移。因此,对于operator delete来说,如果你传给它pb2,它就直接over了。
那么,delete operator怎么可以知道应该怎样传递正确地传递地址过去呢?这是因为,delete operator有点类似于virtual的。要实现这个virtual特性的先决条件就是,你的dtor必须是virtual的。这就可以解释为什么你把virtual注释了,就会over。
至于你把f也注释了,就不crash了。这个原因可能有多种多样的。也许仍然会crash,也许因为优化的原因,....。但是这个仍然是不对的,不能因为不crash就这样用。 |