显式调用子析构函数是否也调用父析构函数

sm81095

对于我正在用C ++编写的内存管理器作为概念证明,为了跟踪分配的对象,我malloc()在一个函数中分配内存,然后将指针返回到该内存并使用placement new运算符。然后,为了跟踪何时删除对象,我将指针传递给另一个函数以调用free()该指针。

但是,由于我使用free()而不是delete,因此不会像通常那样自动调用对象的构造函数,因此我必须自己调用它。而且,由于内存管理器旨在与任何对象一起使用,因此可以想象(甚至有可能)在生命周期的某个时刻,它必须释放可能具有多个父类或在继承树中很深的对象。

我对此的最初解决方案是调用基础对象析构函数,该析构函数将调用所有子析构函数(如果可以相信这个问题),但是由于这些对象实际上可以是任何东西并且具有任何继承集,因此没有知道真正的基类是什么的方法。

所以我的问题是:显式调用子类析构函数是否也会自动调用所有基本析构函数,就像使用delete一样,还是没有办法轻松地做到这一点?

克瑞克(Kerrek SB)

是的,那是保证。C ++ 14 [class.dtor] / 8:

执行完析构函数的主体并销毁主体中分配的所有自动对象后,类X的析构函数调用X的直接非变量非静态数据成员的析构函数,X的直接基类的析构函数(如果X是)。作为最派生类(12.6.2)的类型,其析构函数调用X的虚拟基类的析构函数

具体来说,对于任何类型,T您始终可以执行以下操作:

void * addr = ::operator new(sizeof T);
T * p = ::new (addr) T(/* ctor args */);
p->~T();                                    // !
::operator delete(addr);

或者,如果您不想调用分配器:

{
    std::aligned_storage_t<sizeof(T), alignof(T)> storage;
    T * p = ::new (static_cast<void *>(std::addressof(storage))) T(/* args */);
    p->~T();
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章