判断指针的类型

Determine the type of a pointer

所以我正在制作一个内存堆栈分配器,它能够以连续的方式将任何类型的任何实例分配到堆上。

为了做到这一点,我在每个分配之前直接添加了一个 'AllocationHeader' class,其中包含一个 void* 到实例地址本身,一个 AllocationHeader* 到前一个 header . 到目前为止,这已经完美地工作了,我能够分配和解除分配等。

但是我 运行 有 1 个(可能是 2 个)问题。 为了正确解除分配,我还需要调用相关 object 的析构函数,然后将其从堆栈中删除。 当我删除一个我有指针的实例时这很好,因为我可以将它传递给 deallocate 函数并且它知道它是什么类型并执行它的操作。

问题出在我想创建像 deallocateAll() 或 deallocateAllAboveObject(T* obj) 这样的函数时,因为我需要知道每个分配的类型而不显式传递它们的指针,所以我可以在堆栈在我走的时候调用每个解构器。

我想要的是能够创建一个AllocationHeader,它可以存储任何类型的指针,然后可以在以后检索指针的类型在不知道类型的情况下。

我真的不确定该怎么做,因为到目前为止我看到的所有建议都涉及将 object 与特定类型进行比较并查看它们是否相同。但是我不能只检查程序中每个可能的 class,因为在我继续构建时可能有 1000 个。

或者,如果您对可以处理任何类型的堆栈分配器的替代方法有任何建议,那也很好。

如有任何帮助,我们将不胜感激。

由于 C++ 的静态类型系统,我只能看到几个问题的解决方案

  • 使您使用分配器的每个类型都派生自具有虚拟析构函数的(一致的)类型,例如struct destructible { virtual ~destructible() { } },但是这可能会扩大和改变您更改的任何类型的布局以从中派生。

或者uppon分配存储一个函数对象来进行破坏,例如使用以下模板

template<typename T> void destroy(void* p) { reinterpret_cast<T*>(p)->T::~T(); }

struct AllocationHeader
{
    template<typename T> AllocationHeader(AllocationHeader* previouse, void* data)
        : previouse(previouse), data(data), destructor(&destroy<T>) { }
    AllocationHeader* previouse;
    void* data;
    void (*destructor)(void*);
}
void deallocateAll(AllocationHeader& start)
{
    for (AllocationHeader* a = &start; a != nullptr; a = start->previouse;)
    {
        a->destructor(a->data);
        delete a->data;
    }
}

(如果不提供 AllocationHeader 类型的代码,很难为您提供帮助。)

注意:我的 compiler/IDE 目前正在重新安装,所以我无法测试上面的代码,我很确定其中的大部分代码,除了我可能需要在析构函数中放置一个 typename调用语法 reinterpret_cast<T*>(p).T::~T();

编辑 使用模板构造函数,无法推断模板参数是一个坏主意,应改用以下构造函数

AllocationHeader(AllocationHeader* previouse, void* data, void(*destructor)(void*))
        : previouse(previouse), data(data), destructor(destructor) { }

只需将 &destroy<T> 作为第三个参数传递给它。