C++ new和delete是如何調用構造函數和析構函數的?

幻紫狐狸


在 C++ 中,你也許經常使用 new 和 delete 來動態申請和釋放內存,但你可曾想過以下問題呢?

new 和 delete 是函數嗎?

new [] 和 delete [] 又是什麼?什麼時候用它們?

你知道 operator new 和 operator delete 嗎?

為什麼 new [] 出來的數組有時可以用 delete 釋放有時又不行?

如果你對這些問題都有疑問的話,不妨看看我這篇文章。

new 和 delete 到底是什麼?

如果找工作的同學看一些面試的書,我相信都會遇到這樣的題:sizeof 不是函數,然後舉出一堆的理由來證明 sizeof 不是函數。在這裡,和 sizeof 類似,new 和 delete 也不是函數,它們都是 C++ 定義的關鍵字,通過特定的語法可以組成表達式。和 sizeof 不同的是,sizeof 在編譯時候就可以確定其返回值,new 和 delete 背後的機制則比較複雜。

繼續往下之前,請你想想你認為 new 應該要做些什麼?也許你第一反應是,new 不就和 C 語言中的 malloc 函數一樣嘛,就用來動態申請空間的。你答對了一半,看看下面語句:

string *ps = new string("hello world");

你就可以看出 new 和 malloc 還是有點不同的,malloc 申請完空間之後不會對內存進行必要的初始化,而 new 可以。所以 new expression 背後要做的事情不是你想象的那麼簡單。在我用實例來解釋 new 背後的機制之前,你需要知道 operator new 和 operator delete 是什麼玩意。

operator new 和 operator delete

這兩個其實是 C++ 語言標準庫的庫函數,原型分別如下:

void *operator new(size_t); //allocate an object

void *operator delete(void *); //free an object

void *operator new[](size_t); //allocate an array

void *operator delete[](void *); //free an array

後面兩個你可以先不看,後面再介紹。前面兩個均是 C++ 標準庫函數,你可能會覺得這是函數嗎?請不要懷疑,這就是函數!C++ Primer 一書上說這不是重載 new 和 delete 表達式(如 operator= 就是重載 = 操作符),因為 new 和 delete 是不允許重載的。但我還沒搞清楚為什麼要用 operator new 和 operator delete 來命名,比較費解。我們只要知道它們的意思就可以了,這兩個函數和 C 語言中的 malloc 和 free 函數有點像了,都是用來申請和釋放內存的,並且 operator new 申請內存之後不對內存進行初始化,直接返回申請內存的指針。

我們可以直接在我們的程序中使用這幾個函數。

new 和 delete 背後機制

知道上面兩個函數之後,我們用一個實例來解釋 new 和 delete 背後的機制:

我們不用簡單的 C++ 內置類型來舉例,使用複雜一點的類類型,定義一個類 A:

class A

{

public:

A(int v) : var(v)

{

fopen_s(&file, "test


分享到:


相關文章: