C++11:我可以显式调用基类析构函数来销毁派生类吗?

标签 c++ c++11

我正在用 C++11 实现一个内存池。所有存储在内存池中的对象都需要继承自MemoryPoolObject类,但也可以使用多重继承。

当我分配一个新对象时,我使用 malloc 创建它,然后使用放置构造函数 - 我可以这样做,因为我知道它的类型(allocate() 是一个模板函数,它将类型作为模板参数).我还将其大小存储在其上的对象上(作为 MemoryPoolObject 类的成员变量)。

当我释放对象时,我想调用它的析构函数。但我不再知道对象类型。我知道它派生自 MemoryPoolObject,它有一个虚拟析构函数。所以...如果我显式调用 ~MemoryPoolObject(),这样做是否正确(包括调用任何多重继承基类的析构函数)?

这是一些代码。它没有显示未使用的对象如何在池中存储和检索。但这实际上与手头的问题无关。

class BaseClass
{
public:
    virtual ~BaseClass();
    ...
};

class MemoryPoolObject
{
public:
    virtual ~MemoryPoolObject();

    // In reality I don't just expose this, but for simplicity...
    size_t m_ObjectSize;
};

class ChildClass : public BaseClass, public MemoryPoolObject
{
    virtual ~ChildClass();
    ...
};

// allocation (simplified)
template<class T> 
T* allocate()
{
    size_t objectSize = sizeof(T);
    T* obj = (T*)malloc(objectSize);
    new(obj) T();
    obj->m_ObjectSize = objectSize;
}

// deallocation (also simplified)
void deallocate(MemoryPoolObject* obj)
{
    // Does this call ~BaseClass() and ~ChildClass()?
    obj->~MemoryPoolObject();
}

最佳答案

So... if I make an explicit call to ~MemoryPoolObject(), will that do the right thing (including calling into the destructors of any multiply inherited base classes)?

是的,会的。

但是,我认为您可以稍微更改策略以使您的代码更直观。

MemoryPoolObject中重载operator newoperator delete,让用户使用operator new operator delete 以通常的方式。

示例程序:

#include <iostream>
using namespace std;

void* allocate(size_t s)
{
   // This is a simple implementation.
   // To use a memory pool for allocating objects, this function
   // and deallocate() need to be changed accordingly.

   std::cout << "Allocating memory of size " << s << std::endl;
   return new char[s];
}

void deallocate(void* ptr, size_t s)
{
   std::cout << "Dellocating memory of size " << s << std::endl;
   delete [] static_cast<char*>(ptr);
}

class MemoryPoolObject
{
   public:

      virtual ~MemoryPoolObject() {}

      void* operator new (size_t s)
      {
         return allocate(s);
      }

      void operator delete (void* ptr, size_t s)
      {
         return deallocate(ptr, s);
      }
};

class BaseClass
{
   public:
      virtual ~BaseClass() {}
};

class ChildClass : public BaseClass, public MemoryPoolObject
{
   virtual ~ChildClass() {}
};

int main()
{
   MemoryPoolObject* ptr = new ChildClass;
   delete ptr;
}

输出

Allocating memory of size 16
Dellocating memory of size 16

关于C++11:我可以显式调用基类析构函数来销毁派生类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45948692/

相关文章:

c++ - Microsoft Detours - DetourUpdateThread?

c++ - 独立的多线程进程同时阻塞

c - 获取嵌入式 PACKED_STRUCT 定义以在 g++ 下编译

c++ - 如何按值返回 "auto"返回类型函数

超过 "tuple"的 C++11 范围

python - 使用 C++ 和 Python 访问数组

c++ - 无法初始化以 std::byte 作为成员类型的位域

c++ - 配置 Visual Studio 以创建 32 位和 64 位配置

c++ - 我如何为以下代码进行进程同步?

c++ - 委托(delegate)构造函数的评估