确定指针的类型

时间:2016-04-27 11:51:49

标签: c++ templates memory-management types allocator

所以我正在创建一个Memory Stack Allocator,它能够以连续的方式将任何类型的任何实例分配到堆上。

为了做到这一点,我添加了一个' AllocationHeader'在每次分配之前直接使用类,它包含实例地址本身的void *和前一个头的AllocationHeader *。 到目前为止,这已经完美地运作,并且我能够分配和解除分配等。

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

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

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

我真的不知道该如何做到这一点,因为我目前看到的所有建议都涉及将对象与特定类型进行比较,看看它们是否相同。但是,我无法检查程序中每个可能的类,因为我可以继续在此基础上构建1000个。

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

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

由于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类型的代码,那么难以为您提供帮助。)

注意:我的编译器/ IDE目前正在重新安装,所以我无法测试上面的代码,我对它的大部分内容非常有把握,除了我可能需要在析构函数调用语法typename中放置reinterpret_cast<T*>(p).T::~T(); 1}}

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

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

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