对于我正在用C ++编写的内存管理器作为概念证明,为了跟踪分配的对象,我malloc()
在一个函数中分配内存,然后将指针返回到该内存并使用placement new运算符。然后,为了跟踪何时删除对象,我将指针传递给另一个函数以调用free()
该指针。
但是,由于我使用free()
而不是delete
,因此不会像通常那样自动调用对象的构造函数,因此我必须自己调用它。而且,由于内存管理器旨在与任何对象一起使用,因此可以想象(甚至有可能)在生命周期的某个时刻,它必须释放可能具有多个父类或在继承树中很深的对象。
我对此的最初解决方案是调用基础对象析构函数,该析构函数将调用所有子析构函数(如果可以相信这个问题),但是由于这些对象实际上可以是任何东西并且具有任何继承集,因此没有知道真正的基类是什么的方法。
所以我的问题是:显式调用子类析构函数是否也会自动调用所有基本析构函数,就像使用delete一样,还是没有办法轻松地做到这一点?
是的,那是保证。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] 删除。
我来说两句