类使用定制的内存类重载了new并删除了vs放置了new [英] class overloaded new and delete vs placement new with a bespoke memory class

查看:110
本文介绍了类使用定制的内存类重载了new并删除了vs放置了new的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究使用类重载新闻和删除与刊登位置新闻之间的优缺点.我的意思是,要么声明我希望新建的每个类,然后使用其自己的运算符重载删除它们,要么使用内存管理器通过放置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 newoperator 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆