所以我正在创建一个Memory Stack Allocator,它能够以连续的方式将任何类型的任何实例分配到堆上。
为了做到这一点,我添加了一个' AllocationHeader'在每次分配之前直接使用类,它包含实例地址本身的void *和前一个头的AllocationHeader *。 到目前为止,这已经完美地运作,并且我能够分配和解除分配等。
但是我遇到了1个(可能是2个)问题。 为了正确解除分配,我还需要调用相关对象的析构函数,然后将其从堆栈中删除。 当我删除一个有指针的实例时,这很好,因为我可以将它传递给deallocate函数,它知道它是什么类型并做它的事情。
问题在于我想创建像deallocateAll()或deallocateAllAboveObject(T * obj)这样的函数,因为我需要知道每个分配的类型而不显式传递它们的指针,所以我可以关闭堆栈中的每个分配在我走的时候调用解构器。
我想要的是能够创建一个可以存储任何类型指针的AllocationHeader,然后可以在以后检索指针类型而不必知道类型。
我真的不知道该如何做到这一点,因为我目前看到的所有建议都涉及将对象与特定类型进行比较,看看它们是否相同。但是,我无法检查程序中每个可能的类,因为我可以继续在此基础上构建1000个。
或者,如果您对可以处理任何类型的堆栈分配器的替代方法有任何建议,那么这也很好。
非常感谢任何帮助。
答案 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个参数传递给它。