1. 程式人生 > >New運算子詳解

New運算子詳解

三種new運算子:

new運算子做的三件事:獲得一塊記憶體空間、呼叫建構函式、返回正確的指標

1、new

分配記憶體,呼叫建構函式,定義如下:

void* operator new(std::size_t) throw(std::bad_alloc);

void operator delete(void *) throw();

分配失敗則丟擲異常std::bad_alloc,不是返回NULL,所以判斷返回值是否為NULL是沒用的。

char *p=new char[size]; //分配失敗,不是返回NULL

delete [] p;

2、nothrow new

不丟擲異常。分配失敗時,返回NULL。定義如下:

void* operator new(std::size_t,const std::nothrow_t&) throw();

void operator delete(void*) throw();

char *p=new(nothrow) char[size];//分配失敗,是返回NULL

    if(NULL==p)

    cout<<"alloc failure!"<<endl;

3、placement new

不會記憶體分配失敗,因為它根本不分配記憶體,只調用物件的建構函式。它允許在一塊已經分配成功的記憶體上重新構造物件或物件陣列。定義如下:

void* operator new(size_t,void*);

void operator delete(void*,void*);

使用placement new構造起來的物件或陣列,要顯式呼叫它們的解構函式來銷燬(解構函式並不釋放物件的記憶體),千萬不要使用delete.這是因為placement new構造起來的物件或陣列大小並不一定等於原來分配的記憶體大小,使用delete會造成記憶體洩漏或者之後釋放記憶體時出現執行時錯誤。

當使用new運算子定義一個多維陣列變數或陣列物件時,它產生一個指向陣列第一個元素的指標,返回的型別保持了除最左邊維數外的所有維數。

New運算子的使用方法:

1、new() :分配這種型別的一個大小的記憶體空間,並以括號中的值來初始化這個變數;

2、 new[] :分配這種型別的n個大小的記憶體空間,並用預設建構函式來初始化這些變數;  

char* p=new char[6];     strcpy(p,"Hello");

3、當使用new運算子定義一個多維陣列變數或陣列物件時,它產生一個指向陣列第一個元素的指標,返回的型別保持了除最左邊維數外的所有維數。例如:  

int *p1 = new int[10];

返回的是一個指向int的指標int*  

int (*p2)[10] = new int[2][10];

new了一個二維陣列, 去掉最左邊那一維[2], 剩下int[10], 所以返回的是一個指向int[10]這種一維陣列的指標int (*)[10].  

int (*p3)[2][10] = new int[5][2][10];

 new了一個三維陣列, 去掉最左邊那一維[5], 還有int[2][10], 所以返回的是一個指向二維陣列int[2][10]這種型別的指標int (*)[2][10].

4、建立類物件

1)new建立物件,pTest用來接收物件指標。new申請的物件,則只有呼叫到delete時才會執行解構函式,如果程式退出而沒有執行delete則會造成記憶體洩漏:

CTest*  pTest = new  CTest();  delete pTest;

2)不用new,直接使用類定義申明,使用完後不需要手動釋放,該類解構函式會自動執行:

CTest  mTest;

3)使用普通方式建立的類物件,在建立之初就已經分配了記憶體空間。而類指標,如果未經過物件初始化,則不需要delete釋放:

CTest*  pTest = NULL;