我正在调查使用类重载新闻和删除与放置新闻之间的利弊。我的意思是,要么使用自己的运算符重载声明我可能希望新建和删除的每个类,要么使用内存管理器通过放置 new 为我提供所需的内存。
我有一个内存管理器,允许我从多个池中分配内存:
enum MemPool
{
kPool1,
kPool2,
}
class MemoryManager
{
public:
template <typename T>
void* Allocate(MemPool pool);
void Remove(MemPool pool, void* ptr);
};
MemoryManager g_mmgr;
Allocate 是模板化的,因为在调试模式下我存储了每个分配的名称(通过 typeid(T).name()),我可以通过 sizeof(T) 获取每个分配的大小
我认为自己在如何分配方面至少有 2 个选项,并且正在尝试确定哪个在语法使用、效率、安全性和可移植性方面最好。
选项 1 是有一个带有新闻和删除的模板基类,它封装了内存池并为我很好地键入。
template <typename T, MemPool pool>
class MemPoolUser
{
public:
static void* operator new(int size)
{
return g_mmgr.Allocate<T>(pool);
}
static void operator delete(void* ptr)
{
g_mmgr.Remove(pool,ptr);
}
};
然后我可以确保每个可能需要通过 MemoryManager 更新的类都这样声明:
class MyClass : public MemPoolUser<MyClass, kPool1>
{
};
这将允许我简单地做
MyClass* c = new MyClass();
...
delete c;
并且将调用 MemPoolUser 中正确的 new 和 delete。
选项 2 是使用展示位置新闻:
class MyClass
{
};
MyClass* c = new (g_mmgr.Allocate<MyClass>(kPool1)) MyClass();
....
c->~MyClass();
g_mmgr.Remove(kPool1,c);
这些选项中的每一个都有哪些优点和缺点?选项 1 看起来更简洁,但我必须知道我希望每个类从中分配的内存池的类型,这可能取决于其他运行时因素。
选项 2 更灵活,但新增和删除在语法上很难看(它可以包含在 #defines 中)
所以我的问题是,除了上面提到的问题之外,这两个选项还有什么我没有考虑到的,并且一个比另一个更危险吗?