c 中new與delete的過載

2021-08-10 22:51:32 字數 3364 閱讀 1476

對於有一定程式設計基礎的人來說,new與delete一定會非常的熟悉,知道在使用的過程中:new 先分配memory(記憶體)再呼叫ctor(建構函式);而delete是先呼叫dtor(析構函式)再釋放memory。

int * p=new int[10];

int * pa=new int(10);

new用來動態建立資料或者單個物件;對於上面的**,第一行是用new 動態建立乙個長度為10的資料,指標p指向陣列的首位址;而**第二行是用new建立乙個單個的物件,單個的物件為整型數10,指標pa指向這個物件的位址。

//以下**將new和delete進行了全域性過載

void * myalloc(size_t size)

void myfree(void * ptr)

//它們不可以被申明在乙個namespace內

inline

void * operator new(size_t size)

inline

void * operator new(size_t size)

inline

void operator delete(void * ptr)

inline void operator delete(void * ptr)

如果程式中寫成上面的**形式,則此時new和delete被過載成了全域性的形式。那麼如果對乙個class裡面過載 member operator new/delete 應該如何操作呢,請看下面的參考**(如果需要對乙個class中的new和delete進行過載可以參考下面的**(下方**的「…」部分需要使用者根據自己的需求進行自定義)

//以下**適合在乙個class中對new 和delete的過載過程進行理解(僅供參考)

class foo

foo(int i) :_id(i)

//virtual

~foo()

static void * operator new(size_t size);

static void operator delete(void * pdead, size_t size);

static void * operator new(size_t size);

static void operator delete(void *pdead, size_t size);

};void * foo::operator new(size_t size)

void foo::operator delete(void * pdead, size_t size)

void * foo::operator new(size_t size)

void foo::operator delete(void * pdead, size_t size)

使用時用法:

foo * pf = new foo;

delete pf;

foo * pd = new foo[size];

delete pd;

通過上方的例子相信大家對於在c++中如何實現new和delete的全域性過載,以及在乙個class中對new和delete進行過載有了一定的了解,但是我們要記住的是new與delete是配套出現的,尤其是對於new乙個資料時,最後必須要有配套的delete對其進行記憶體的釋放。

但是對new和delete使用中如果遇到下方的這種情況則一定需要注意(如下):

foo * pf=::new foo;

delete pf;

如果遇到上面的這種情況,即:使用者已經在class中對new和delete進行了過載,但是使用中如果遇到上面這種情況(在new的前面加上「::」符號)時,則表示此時繞過了自己過載的運算子new,而是呼叫了全域性的new運算子。

對於上面的**裡面寫的class foo中的資料成分,可以知道,含有乙個int型資料,乙個long型資料,乙個string型資料,而從記憶體的角度分析:乙個int佔4個位元組,乙個long型資料也是佔4個位元組,而乙個string型的資料它實際是乙個指標,而乙個指標佔4個位元組,所以此時我們如果要求foo占得位元組,可以得到:

sizeof(foo)的值為12
& 如果給foo 類新增乙個虛函式時,更具我之前說的虛指標與虛表的分析可以知道當加上了虛函式後,那麼它的物件就會多乙個指標,而乙個指標佔4個位元組,則加上虛函式後sizeof(foo)=16.

那麼如果對於foo這個型別,我需要new乙個資料型別為foo的陣列,它的記憶體又是如何變化的呢,如下:

foo * array=new foo[5];

delete array;

那麼此時sizeof(foo)=64;大家可能會覺得奇怪,乙個單一的foo物件sizeof的值是12,那麼上面的這個陣列對應的sizeof不是應該是12*5=60麼,多出的4個位元組是**來的。其實當new乙個陣列時,foo型別這個陣列實際佔的位元組大小等於array的整包大小12乘以5等於60,然後在加上乙個計數器來記錄有幾個foo型別的資料,而這個計數器的大小佔4個位元組,所以最後他的大小60+4=64個位元組。那麼如果與virtual結合呢,他的大小將變成(12+4)*5+4=84個位元組。

遇到過載new()和delete()時:

在這之前我們說的new和delete的過載,是operator new;operator delete和operator new;oprator delete,除了這兩種過載方法外,我們還可以過載class member operator new(),寫出多個版本,前提是每乙個版本的宣告都必須有獨特的引數列,其中**第一引數必須是size_t 型,**其餘引數以new所指定的placement arguments 為初值,出現new(…),小括號內便是所謂的placement argument 。如:

foo * pf=new(300,'c')foo;
我們也可以過載class member operator delete(),寫出多個版本,但他們絕不會被delete呼叫,只有當new所呼叫掛的ctor(建構函式)跑出exception時才會呼叫這些過載版的operator delete(),它只可以這樣來呼叫,主要用來歸還未能完全建立成功的object所占用的memory。

下方為new()的參考:

void * oprerator new(size_t size ,void * start)

void * operator new(size_t size ,long extra)

void * operator new(size_t size ,long extra,char inti)

new與delete的過載

include stdafx.h include using namespace std include include new 和delete的過載 new new delete delete 適用於極個別情況需要定製的時候才用的到。一般很少用 宣告可以不加 引數 void operator ne...

過載C 的new和delete

過載c c 標準庫的記憶體管理函式 比如malloc,free,operator new,operator delete,operator new,operator delete 時,編譯器會忽視重定義,所以不用擔心鏈結時會產生重定義錯誤。operator new,operator delete,o...

C 中的new與delete總結

標準庫提供的global operator new,在全域性名字空間中定義 void operator new std size t size 丟擲異常的版本 void operator new std size t size,const std nothrow t nothrow value no...