1. 程式人生 > >C++中的placement new--在指定位置呼叫某類的建構函式

C++中的placement new--在指定位置呼叫某類的建構函式

[size=large]先貼上參考資料的網址:[/size]
1、[url]http://www.builder.com.cn/2008/0104/696370.shtml[/url]
2、[url]http://c.chinaitlab.com/basic/783582_2.html[/url]

[size=large]感覺自己用的話不需要過載new運算子,畢竟都是要分配記憶體,呼叫建構函式。。自己做記憶體管理直接申請一塊大記憶體用placement new建立物件就好了。
另外,明白了delete與delete[] 的區別在於delete[]回收記憶體前還會逐個呼叫解構函式,因而對於簡單型別等無需析構的兩者沒啥區別。[/size]

#pragma  once
#include "iostream"
//#include <new.h>

using namespace std;

class A
{
public:
int a;
int* pInt;
A(){
pInt=new int[10];
}


A(int a):a(a){
pInt=new int[10];
}

~A(){
cout<<"A的解構函式!!a="<<a<<";\tpInt="<<(long long)pInt<<endl;
if(pInt!=NULL)
{
delete[] pInt;
pInt=NULL;
}
}


// void* operator new(size_t size)
// {
// cout<<"operator new called"<<endl;;
// return ::operator new(size);
// }

// void* operator new(size_t /*省略名稱以防編譯器警告*/,void* location=(void*)0){//placement new ,如 new(p) A(3); //p->A::A(3); //必須#include <new>
// cout<<"placement new called"<<endl;
// return location;
// }

};

// void* operator new(size_t size)
// {
// cout<<"global new"<<endl;
// return malloc(size);
// }


void main(){
//A* a = new A();
A a(1);

char* s=new char[sizeof(A)];
A* p = (A*)s;
cout<<"before 'new(p) A(2);' p->a = "<<p->a<<";\tpInt="<<(long long)p->pInt<<endl;
new(p) A(2); //p->A::A(2); //placement new!!!!!!!!!!
cout<<"after 'new(p) A(2);' p->a = "<<p->a<<";\tpInt="<<(long long)p->pInt<<endl;
//p->~A();//需要手動呼叫解構函式!!!


cout<<"\n****************** test2"<<endl;
char* s2=new char[sizeof(A)];
A* p2 = (A*)s2;
cout<<"before 'p2->A::A(3);' p2->a = "<<p2->a<<";\tpInt="<<(long long)p2->pInt<<endl;
p2->A::A(3);//placement new!!!!!!!!!! 的第二種寫法
cout<<"after 'p2->A::A(3);' p2->a = "<<p2->a<<";\tpInt="<<(long long)p2->pInt<<endl;
// p2->~A();


delete[] s;//編譯器不知道s中的內容是類A啊,不呼叫解構函式
delete[] s2;

//測試陣列
// cout<<"\n\\\\\\\\\\\\*****測試陣列"<<endl;
// A* aa=new A[10];
// delete[] aa;

cout<<"\n****************** 從main函式返回前的最後一句"<<endl;
}


[color=red][size=large]輸出如下:[/size][/color]
[img]http://dl.iteye.com/upload/attachment/0076/5596/9e5b559b-edb8-35ab-a3a0-8cb610fd102a.png[/img]