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();
}
萨胡

所以...如果我显式调用~MemoryPoolObject(),这会做正确的事情(包括调用任何多重继承基类的析构函数)?

是的,它会的。

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

重载operator newand operator deleteinMemoryPoolObject并让用户以通常的方式使用operator newand 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

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在C ++继承中,当指向基类的指针对象指向派生类时,不调用派生类析构函数

C ++ 11在派生类中删除的析构函数

C ++ Qt基类虚拟析构函数

c ++-通过抽象模板基类接口指针访问派生类方法,而接口中没有显式类型

C#-在派生类中调用基类和类构造函数

C ++破坏顺序:在类析构函数之前调用字段析构函数

C ++:显式调用模板参数的typedef的析构函数

派生类是否可以具有不在C ++基类中的构造函数?

C ++:在派生类成员上调用基类方法

在C ++中从派生类的析构函数调用虚函数

C ++派生类构造函数调用基类构造函数错误

在C ++中从构造函数中显式地调用析构函数是不好的做法吗?

C ++多态性:是否可以使用从双重派生类到基类的函数?

为什么在构造时调用C ++类的析构函数?

C ++继承:使用派生类的实例调用基类的虚函数

C ++如何从多个派生类调用基类方法?

如何在C ++中从基类构造函数调用派生类方法?

我们什么时候必须在派生类c ++中定义一个析构函数

C ++派生类和虚拟析构函数

从基类析构函数调用派生类方法

C ++继承:指向基类的派生类指针调用派生类方法

可以将匿名派生类的地址分配给基类指针C ++吗?

C ++多态性:派生类调用基类虚拟函数,而不是重写的派生类

C++ 可以使析构函数不调用类成员的析构函数和基类的析构函数吗?

基类和派生类 c++11

C++ 可以根据给单个构造函数的参数创建派生类而不是bass 类吗?

在派生类 C++ 的构造函数中调用基类的构造函数

C++ 派生类调用函数

C# 可以让基类中的泛型函数知道调用派生类的类型吗?