C++ Placement New

2125 ワード

まず一つのテーマを見てみましょう.
 
#include <stdio.h>

#include <iostream>

using namespace std;



struct Base 

{

	int j; 

	virtual void f()

	{

		printf("B
"); } }; struct Derived: Base { void f() { printf("D
"); } }; void fooBar() { Base b; b.f(); //B b.~Base(); new ( &b ) Derived; b.f(); //B } int main(int argc, char *argv[]) { fooBar(); return 0; }

印刷されたのは2つのBで、好奇心があったのでplacement newを調べました.
 
placement newはoperator newをリロードする標準的でグローバルなバージョンであり、カスタマイズされたバージョンに置き換えることはできません(通常のoperator newやoperator deleteのようにユーザーカスタマイズされたバージョンに置き換えることはできません).
その原型は以下の通りです.
void *operator new( size_t, void *p ) throw()  { return p; }
まず、混同しやすいキーワードをいくつか区別します.new、operator new、placement newです.
newオペレータとdeleteオペレータは、スタック内のメモリを申請して解放する必要がありますが、どちらも再ロードできません.異なるメモリ割り当て動作を実現するには、newやdeleteではなくoperator newを再ロードする必要があります.
次のコードを参照してください.
class MyClass {…};
MyClass * p=new MyClass;
ここでnewは実際には次の3つのプロセスを実行します.
1 operator new割り当てメモリを呼び出す.
2コンストラクション関数を呼び出してクラスオブジェクトを生成します.
3該当するポインタを返します.
operator newはoperator+のようにリロードできますが、void operator new(size_t size)というプロトタイプをグローバルにリロードすることはできません.一般的にクラスでのみリロードできます.クラスにoperator newがリロードされていない場合、呼び出しはグローバルです.operator newはスタックの割り当てを完了します.同様に、operator new[]、operator delete、operator delete[]もリロードできます.一般的には、そのうちの1つをリロードする場合は、残りの3つをリロードしたほうがいいです.
placement newはoperator newのリロードバージョンですが、あまり使いません.割り当てられたメモリにオブジェクトを作成したい場合は、newを使用してはいけません.すなわちplacement newでは、割り当てられたメモリ(スタックまたはスタック)に新しいオブジェクトを構築できます.プロトタイプのvoid*pは、実際には割り当てられたメモリバッファのヘッダアドレスを指します.
newオペレータを使用してメモリを割り当てるには、スタック内で十分な空き領域を検索する必要があることを知っています.この操作速度は遅いです.メモリが割り当てられないという異常も発生する可能性があります(スペースが足りない).placement newでこの問題を解決できます.オブジェクトを構築するのは、メモリを検索する必要がなく、メモリ割り当ての時間が定数であり、プログラムの実行中にメモリ不足の異常が発生することはありません.そのため、placement newは時間に対する要求が高く、長時間に適しています.中断したくないアプリケーションを実行します.
参照先:
http://hi.baidu.com/jakisou/item/2f663ff42ab4e219a62988fb