类使用定制的内存类重载了new并删除了vs放置了new [英] class overloaded new and delete vs placement new with a bespoke memory class
问题描述
我正在研究使用类重载新闻和删除与刊登位置新闻之间的优缺点.我的意思是,要么声明我希望新建的每个类,然后使用其自己的运算符重载删除它们,要么使用内存管理器通过放置new来给我所需的内存.
我有一个内存管理器,可以让我从多个池中分配内存:
enum MemPool
{
kPool1,
kPool2,
}
class MemoryManager
{
public:
template <typename T>
void* Allocate(MemPool pool);
void Remove(MemPool pool, void* ptr);
};
MemoryManager g_mmgr;
分配是模板化的,因为在调试模式下,我存储每个分配的名称(通过typeid(T).name()),我可以通过sizeof(T)获得每个分配的大小
我认为自己在如何分配方面至少有两个选择,并且正在尝试确定在句法用法,效率,安全性和可移植性方面哪一个最好.
选项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包装)
所以我的问题是,除了上述提到的问题之外,在这两种选择中我还有其他没有想到的地方吗?还有一种危险比另一种危险吗?
如果您必须首先这样做(我希望您确实有相当不错的用例,其中对特定的内存池有一些特定的需求)对于这些对象),我肯定会使用operator new
和operator delete
解决方案.它允许您编写使用此代码的应用程序代码,并在典型代码之上和之下添加最少的额外代码.
I am investigating the pros and cons between using class overloaded news and deletes vs placement news. By this I mean, either declaring every class I may wish to new and delete with their own operator overloads, or by using the memory manager to give me the memory I need via placement new.
I have a memory manager that allows me to allocate memory from a number of pools:
enum MemPool
{
kPool1,
kPool2,
}
class MemoryManager
{
public:
template <typename T>
void* Allocate(MemPool pool);
void Remove(MemPool pool, void* ptr);
};
MemoryManager g_mmgr;
The Allocate is templated since in debug mode I store the name of each allocation (via typeid(T).name()) and I can get the size of each allocation via sizeof(T)
I see myself as having at least 2 options as to how to allocate and am trying to decide which is best in terms of syntactical usage, efficiency, safety and portability.
Option 1 is to have a templated base class with news and deletes, which wraps up the mempool and type nicely for me.
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);
}
};
I could then ensure that every class that may need newing via the MemoryManager is declared thus:
class MyClass : public MemPoolUser<MyClass, kPool1>
{
};
This will allow me to simply do
MyClass* c = new MyClass();
...
delete c;
and the correct new and delete inside MemPoolUser will be called.
Option 2 is to use placement news:
class MyClass
{
};
MyClass* c = new (g_mmgr.Allocate<MyClass>(kPool1)) MyClass();
....
c->~MyClass();
g_mmgr.Remove(kPool1,c);
Any pros and cons to each of these options? Option 1 seems neater, but I have to know the type of mempool I want each class to allocate from, which may depend on other runtime factors.
Option 2 is more flexible but the newing and deleting is syntactically ugly (it could be wrapped in #defines)
So my question is, apart from the above problems mentioned, is there anything else I have failed to consider with these two options and is one more hazardous than the other?
If you MUST do this in the first place (and I expect you do have some pretty decent use-case where which has some specific need for a specific memory pool for these object), I would definitely go for the operator new
and operator delete
solution. It allows your application-code that uses this to be written with a minimal amount of extra coding above and beyond the typical code.
这篇关于类使用定制的内存类重载了new并删除了vs放置了new的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!