简体   繁体   English

明确调用子析构函数还会调用父析构函数吗

[英]Does Explicitly Calling Child Destructors also call Parent Destructors

For a memory manager that I am writing in C++ as a proof of concept, in order to keep track of allocated objects I am allocating memory with malloc() in a function, then returning the pointer to that memory and using the placement new operator. 对于我用C ++编写的内存管理器作为概念证明,为了跟踪分配的对象,我在函数中使用malloc()分配内存,然后将指针返回到该内存并使用placement new运算符。 Then, to track when the object is deleted, I pass the pointer into another function to call free() on the pointer. 然后,为了跟踪何时删除对象,我将指针传递到另一个函数中,以对该指针调用free()

However, since I am using free() instead of delete , the object's constructor is not automatically called like it usually is, so I have to call it myself. 但是,由于我使用的是free()而不是delete ,因此不会像通常那样自动调用对象的构造函数,因此我必须自己调用它。 Also, since the memory manager is designed to work with any object, it is conceivable (and even likely) that at some point in it's lifetime it will have to free an object that potentially has multiple parent classes or is deep within an inheritance tree. 而且,由于内存管理器旨在与任何对象一起使用,因此可以想象(甚至有可能)在其生命周期的某个时刻,它必须释放可能具有多个父类或在继承树中很深的对象。

My initial solution to this would be to call the base objects destructor, which would call all of the child destructors (if this question is to be believed), but since the objects could literally be anything and have any set of inheritance, there is no way to know what the true base class for it is. 我对此的最初解决方案是调用基础对象析构函数,该析构函数将调用所有子析构函数(如果可以相信这个问题 ),但是由于这些对象实际上可以是任何东西并且具有任何继承集,因此没有知道真正的基类是什么的方法。

So my question is: will explicitly calling the child classes destructor automatically call all of the base destructors as well, like with delete, or is there no way to easily do this? 所以我的问题是:是否显式调用子类析构函数也会自动调用所有基本析构函数,就像使用delete一样,还是没有办法轻松地做到这一点?

Yes, that's guaranteed. 是的,那是保证。 C++14 [class.dtor]/8: C ++ 14 [class.dtor] / 8:

After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X 's direct non-variant non-static data members, the destructors for X 's direct base classes and, if X is the type of the most derived class (12.6.2), its destructor calls the destructors for X 's virtual base classes. 执行完析构函数的主体并销毁主体中分配的所有自动对象后,类X的析构函数调用X的直接非变量非静态数据成员的析构函数, X的直接基类的析构函数,以及如果X是最派生类的类型(12.6.2),则其析构函数调用X的虚拟基类的析构函数。

Specifically, for any type T you can always do this: 具体来说,对于任何T类型,您始终可以执行以下操作:

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

Or, if you didn't want to invoke an allocator: 或者,如果您不想调用分配器:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM