クラスのオーバーロードされたニュースと削除と配置ニュースの使用の長所と短所を調査しています。つまり、new および delete するすべてのクラスを独自の演算子のオーバーロードで宣言するか、メモリ マネージャーを使用して配置 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 は、ニュースと削除を含むテンプレート化された基本クラスを用意することです。これにより、mempool がラップされ、適切に入力されます。
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 を介した newing が必要なすべてのクラスが次のように宣言されるようにします。
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 の方がすっきりしているように見えますが、各クラスに割り当てたい mempool のタイプを知る必要があります。これは、他のランタイム要因に依存する可能性があります。
オプション 2 はより柔軟ですが、新規作成と削除は構文的に醜いです (#defines でラップすることができます)。
だから私の質問は、上記の問題とは別に、これら2つのオプションで考慮に入れなかったものは他にあり、一方は他方よりも危険ですか?