位置決めnew演算子


位置決めnew
2007-10-08 18:03:02|分類:技術総括|通報|番号購読
予め定義されたメモリ位置にオブジェクトを構築する
事前に定義されたメモリの場所でオブジェクトを構築する方法について、C++の質問をすることがよくあります.予め定義されたメモリバッファでオブジェクトを構築するには、多くの有用なアプリケーションがあります.たとえば、カスタムゴミ収集器は、大きな事前割り当てメモリバッファを使用して、ユーザーがこのバッファでオブジェクトを構築することができます.これらのオブジェクトが不要になった場合、ストレージスペースは自動的に回収されます.この技術は時間重視の応用にも有用である.予め割り当てられたメモリバッファでオブジェクトを構築するのは、プログラム割り当て操作自体が貴重な時間を無駄にしないため、「時間定数」操作です.また、システムに十分なメモリがない場合、動的メモリ割り当てが失敗する可能性があることにも注意してください.したがって,タスクを重視するアプリケーションに対しては,十分なバッファを予め割り当てることが避けられない場合がある.多くのアプリケーションでは、所定の時間に異なるタイプのオブジェクトを構築する必要があります.このような例を考えてみると、GUIアプリケーションはユーザーの入力に応じて、毎回、異なるダイアログボックスを表示し、メモリの割り当てと解放を繰り返すことができ、このアプリケーションは事前にメモリバッファを作成し、このバッファの中で異なるタイプのオブジェクトを繰り返し構築し、破棄することができる.C++は、予め決定されたメモリ位置でオブジェクトを構築するタスクを容易にするためのいくつかの特徴を提供します.これらの特徴には、「位置決めnew」(placement new)操作と呼ばれる特殊な形式のnewオペレータと、明示的な解析処理が含まれる.実装方法は次のとおりです.最初のステップ:所定のタイプのオブジェクトを格納するために十分なメモリバッファを割り当てます.異なるタイプのオブジェクトを構築するたびに、少なくとも最大のオブジェクトが占める空間のサイズでバッファを割り当てる必要があります.プリ割り当てされたバッファは、使用可能なメモリ領域に割り当てられた純粋な文字配列です.char * buff = new char [sizeof (Foo) ]; バッファが割り当てられると、バッファに各タイプのオブジェクトを構築できます.このため、バッファアドレスをplacement newのパラメータとして、特殊バージョンのnewオペレータ(「位置決めnew」)を使用します.placement newを使用するには、標準ヘッダファイルを含める必要があります.次のコード・スライスでは、placement new操作を使用してメモリ・アドレスbuffにFooタイプのオブジェクトを構築します.include Foo * pfoo = new (buff) Foo;//newアクションを使用して、以前に割り当てられたバッファアドレスをパラメータとしてFoo Placement newを構築し、このバッファに所定のタイプのオブジェクトを構築します.彼はオブジェクトを構築するポインタを返します.このオブジェクトポインタの使用は通常のポインタの使用と変わらないです.unsigned int length = pfoo->size();  pfoo->resize(100, 200); length = pfoo->size();このオブジェクトが不要になった場合、その構造関数を明示的に呼び出して空間を解放する必要があります.このことをするにはいくつかのテクニックがあります.多くの人がオブジェクトが自動的に破棄されると勘違いしているので、間違っています.事前に割り当てられたバッファで別のオブジェクトを構築する前に、またはバッファを解放する前に、構造関数を明示的に呼び出すことを忘れた場合、プログラムは予想できない結果を生じます.明示的な解析器は、pfoo->~Foo()//明示的呼び出し構造関数換言すると、明示的な解析器は通常のメンバー関数呼び出しと同じですが、名前は通常のメンバー関数と少し違います.オブジェクトが破棄されると、割り当てられたメモリに別のオブジェクトを再構築できます.実際には、このプロセスは、オブジェクトを構築し、破棄し、割り当てられたバッファを再利用して新しいオブジェクトを構築することを制限なく繰り返すことができます.事前定義されたバッファが不要になった場合、またはアプリケーションが閉じた場合、事前定義されたバッファを解放する必要があります.delete[]を使用して、事前に定義されたバッファが文字配列であるため、このタスクを完了します.次のコードには、最終バッファの解放を含む完全な例のすべてのステップが含まれます.
#include <new>

  void placement_demo()
  { 
    //1.      
    char * buff = new char [sizeof (Foo) ];  

    //2.    placement new
    Foo * pfoo = new (buff) Foo;  
    
    //    
    unsigned int length = pfoo->size();  
    pfoo->resize(100, 200);

    //3.         
    pfoo->~Foo();  
    
    //4.         
    delete [] buff;  
  }