1

C++ でのコンテナーの実装に出くわしました。そのクラスは、内部バッファを使用してそのオブジェクトを管理します。これは、安全チェックなしの簡易バージョンです。

template <typename E> class Container
{
public:
   Container() : buffer(new E[100]), size(0) {}
   ~Container() { delete [] buffer; }

   void Add() { buffer[size] = E(); size++; }
   void Remove() { size--; buffer[size].~E(); }

private:
   E* buffer;
   int size;
};

私の知る限り、 /がカスタマイズされていない場合、これはEオブジェクトを重複してContainer()構築/破棄します。これは危険なようです。~Container()newdelete

危険な冗長なコンストラクタ/デストラクタの呼び出しを防ぐための最良の方法で配置newを使用しAdd()ていますか (クラスを完全な機能のプールにバインドすることは別として)?

配置を使用する場合newnew char[sizeof(E)*100]バッファを割り当てる正しい方法はありますか?

4

2 に答える 2

3

E私の知る限り、これはオブジェクトを冗長に構築/破棄します

そう見えるだろう。ed 配列はnewすでにデフォルトのコンストラクターを適用してdelete[]おり、すべての要素に対してデストラクタも呼び出します。実際には、 メソッドAdd()とメソッドは、カウンターRemove()を維持する以外にはほとんど追加しません。size

プレースメント new を使用する場合new char[sizeof(E)*100]、バッファを割り当てる正しい方法はありますか?

最善の方法は、std::allocatorすべてのメモリの問題を既に処理している を選択することです。

プレースメントを使用してnew自分でメモリを管理するには、いくつかの問題 (以下を含む) を認識する必要があります。

  • アライメント
  • 割り当てサイズと使用サイズ
  • 破壊
  • 定置などの建設上の問題
  • エイリアシングの可能性

これらのどれも克服することが不可能ではなく、標準ライブラリで既に行われています。カスタム アロケータを追求することに関心がある場合は、グローバル割り当て関数( void* operator new (std::size_t count);) がメモリ割り当ての適切な開始点になります。


コードの本来の目的についてこれ以上説明しなければ、コンテナー内の要素を管理するには、 astd::vectorまたは a のstd::array方がはるかに優れたオプションになります。

于 2016-02-01T11:39:03.313 に答える