本文參考地址 http://www.cnblogs.com/luxiaoxun/archive/2012/08/10/2631812.html
new operator
就是new 操作符:
- 調(diào)用
operator new
分配足夠的內(nèi)存空間,調(diào)用對象的構(gòu)造函數(shù) - 不能被重載
operator new
是函數(shù):
- 只分配內(nèi)存拦键,不調(diào)用構(gòu)造函數(shù)
- 可以被重載
- 重載時花盐,返回值類型必須聲明為void *
- 重載時,第一個參數(shù)必須是要求分配空間的字節(jié)大小,類型是
size_t
- 重載時,允許攜帶其他參數(shù)呢蔫。
例子:
#include <iostream>
#include <string>
using namespace std;
class X{
public:
X(){
cout<<"constructor"<<endl;
}
void* operator new(size_t size, string str){
cout<< "operator new " << size << " " << str << endl;
return ::operator new(size);
}
void operator delete(void* pointer){
cout << "operator delete" <<endl;
::operator delete(pointer);
}
~X(){
cout<<"destructor"<<endl;
}
};
int main(){
X *x = new ("str") X;
delete x;
return 1;
}
placement new
placement new 是重載operator new 的一個標(biāo)準(zhǔn)、全局的版本洞辣,它不能夠被自定義的版本代替(不像普通版本的operator new和operator delete能夠被替換)咐刨。原型為:
void *operator new( size_t, void * p ) throw() { return p; }
placement new
的執(zhí)行忽略了size_t參數(shù)昙衅,只返還第二個參數(shù)扬霜。其結(jié)果是允許用戶把一個對象放到一個特定的地方,達(dá)到調(diào)用構(gòu)造函數(shù)的效果而涉。和其他普通的new不同的是著瓶,它在括號里多了另外一個參數(shù)。
palcement new 存在理由
- 空間啼县。不分配新的內(nèi)存材原,而是構(gòu)造一個新對象到預(yù)分配的內(nèi)存上沸久。
- 時間。new 操作符分配內(nèi)存余蟹,需要在堆上查詢足夠大的內(nèi)存空間卷胯,而且會存在不能分配的異常(內(nèi)存不足);placement new 是在已有的內(nèi)存上構(gòu)造對象威酒,不查找內(nèi)存窑睁,分配內(nèi)存的時間復(fù)雜度為常數(shù),且不存在內(nèi)存分配異常的情況葵孤。適合時間要求高和長時間允許不被打斷的程序担钮。
placement 使用需要五步
緩存提前分配,有三種方式:
在堆上進行分配class Task :
char * buff = new [sizeof(Task)];
在棧上進行分配class Task:
char buf[N*sizeof(Task)];
還有一種方式,就是直接通過地址來使用尤仍。(必須是有意義的地址)
void* buf = reinterpret_cast<void*> (0xF00F);
- 第二步:對象的分配
剛才已分配的緩存區(qū)調(diào)用placement new來構(gòu)造一個對象:
Task *ptask = new (buf) Task
- 第三步:使用
按照普通方式使用分配的對象:
ptask->memberfunction();
ptask->member;
- 第四步:對象的析構(gòu)
一旦你使用完這個對象箫津,你必須調(diào)用它的析構(gòu)函數(shù)來毀滅它。
ptask->~Task(); //調(diào)用外在的析構(gòu)函數(shù)
第五步:釋放
你可以反復(fù)利用緩存并給它分配一個新的對象(重復(fù)步驟2宰啦,3苏遥,4)如果你不打算再次使用這個緩存,你可以象這樣釋放它:
delete [] buf;
跳過任何步驟就可能導(dǎo)致運行時間的崩潰赡模,內(nèi)存泄露暖眼,以及其它的意想不到的情況。如果你確實需要使用placement new,請認(rèn)真遵循以上的步驟诅病。
#include <iostream>
using namespace std;
class X
{
public:
X() { cout<<"constructor of X"<<endl; }
~X() { cout<<"destructor of X"<<endl;}
void SetNum(int n)
{
num = n;
}
int GetNum()
{
return num;
}
private:
int num;
};
int main()
{
char* buf = new char[sizeof(X)];
X *px = new(buf) X;
px->SetNum(10);
cout<<px->GetNum()<<endl;
px->~X();
delete []buf;
return 0;
}