C++ new 的用法 (總結)

來源:互聯網
上載者:User

標籤:c++

C++ new 的基本和進階用法推薦文章 http://kelvinh.github.io/blog/2014/04/19/research-on-operator-new-and-delete/new 的基本用法
int *a = new int[5];class A {...}   //聲明一個類 AA *obj = new A();  //使用 new 建立對象delete []a;delete obj;

這裡我們注意,new int[5] 僅僅分配了空間, 但是 new A(),不僅僅為對象obj在隊上分配了空間, 而且還調用了 A的建構函式,產生了這個對象。
所以 new A() 這樣方式的功能如下:
- 在堆上分配空間
- 在分配的空間上調用對象的建構函式
(這也是 new 和 malloc的主要區別,是否調用建構函式)

同理: 在調用 delete obj的時候:
1. 首先調用 這個對象 的解構函式
2. 然後釋放這個對象的空間

new 的升級版本 (version 1)

從上面可以看到:new 的功能是 1. 分配空間, 2 調用建構函式。 那麼到底是如何?的呢?

其實 C++ 規定 new 的 這 兩個功能分開實現:
1. 分配空間: 調用函數 operator new 來實現。
2. 調用建構函式: 調用 placement new 來實現。

現在有三個 new 了,第一個new就是我們常說的new, 這個new 調用 接下來的兩個new 來實現它的功能。 (我們稱這個 new 為, new operator,叫做“new 運算式”,因為operator 在 new 後面,所以 叫做 “new 運算式”,也就是關鍵字)

new關鍵字 會調用 operator new 分配空間: 這裡 operator new 是一個全域的函數,寫在一個檔案中。當使用 new 關鍵字 的時候,編譯器會自動找到這個函數,並且調用這個函數:這個函數的聲明如下:

// 全域 operator newvoid * operator new(std::size_t size) throw(std::bad_alloc) {    if (size == 0)        size = 1;    void* p;    while ((p = ::malloc(size)) == 0) { //採用 malloc 分配空間        std::new_handler nh = std::get_new_handler();        if (nh)            nh();        else            throw std::bad_alloc();    }    return p;}// 對應的全域 operator delete 採用 free 釋放空間void operator delete(void* ptr) {    if (ptr)        ::free(ptr); //採用 free 釋放空間。}

這個 operator new 函數稱為 全域 operator new 。 (這裡稱為 全域 主要是因為 每個類 還可以 重載 自己的 operator new() 函數)

全域 operator new 分配空間

從上個例子中可以看到, 全域 operator new 分配空間,簡單的調用了 malloc() 函數來分配空間。 並沒有做任何初始化工作。

現在問題來了: 已經有了一段分配好的空間 ,如何在這個空間上 調動這個類的建構函式,從而真正的建立一個對象呢? (你需要對 對象的 記憶體模型 有一定的瞭解)。 解決方案是: placement new

placement new 調用建構函式

placement new 的功能就是 在一個 已經分配好的空間上,調用建構函式,建立一個類。
placement new 就這一個用法,知道如何用就可以了,它不是一個(寫在檔案中)函數,是編譯器編譯時間候做的事情。

用法如下:

void *buf = // 在這裡為buf分配記憶體Class *pc = new (buf) Class();  

舉例子:

    class A {...}  //聲明一個 類 A    void *buf =  malloc(sizeof(A));   //簡單地分配空間。    A *ojb = new (buf)A();    // 在分配的空間上調用建構函式。

現在問題來了: 這裡 的空間可以是任意的空間嗎,答案是的! 這裡的 “已經分配好的空間” 可以是任何的空間,比如說 可以是棧上的空間!

    class A {int a;}    int buf[sizeof(A)];   //在棧上,分配一個數組    A *obj =  new(buf) A();  //在這個數組上構造一個 對象 A。
new 的升級版本 (version 2)

我們稱上一個 operator new 為 全域operator new ,因為它是一個檔案中的函數。
1. 於是我們就可以對 operator new 進行重載了:
2. 重載之後,我們可以在其中自己進行記憶體配置。(比如說,不使用 malloc進行實現)

但是重載 operator 必須非常的注意!
文章說的非常好, 有非常多的注意事項! 有好處也有壞處,
陳碩的文章 說的也非常好! 值得一看,看不懂別怪我。

這裡的升級版本是: 可以在類中重載 operator new 和 placement new。 這個需要在 google 上搜尋一下。

new 的用法!

當我們自己重載了 new 之後,就可以進行記憶體管理了,必須說構造一個記憶體池! 當然,這是下一篇文章的內容了。

(文章還會在不斷的修改的)

C++ new 的用法 (總結)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.