C++ new operator、operator new 和 placement new

1. new operator

概念:new是C++中動態內存分配的運算符,同時也是一個關鍵字,在C語言中分配內存一般使用malloc函數。

規則:

  • 不可以被重載;
  • 當new分配內存失敗,會調用分配內存失敗處理程序new_handler;

執行過程:

  1. 調用operator new 分配內存;
  2. 調用構造函數生成類對象;
  3. 返回相應指針;

使用舉例:

#include <iostream>
using namespace std;

class Node{
    public:
        Node(int _x):x(_x){}
    private:
        int x;
};
int main(){
    //申請
    int *p = new int;               //普通分配
    int *p1 = new int[2]{0,1};      //分配數組
    Node *p2 = new Node(10);        //分配對象
    //釋放
    delete p;
    delete [] p1;
    delete p2;
}

2. operator new

規則:

  • 可以被重載,有重載則優先調用重載,無則調用全局的;
  • 重載時,第一個參數類型必須爲要求分配空間的大小,類型爲size_t;
  • 重載時,返回類型必須聲明爲void*,可以帶其它參數;
  • 只分配所要求的空間,不調用相關對象的構造函數;

使用舉例:

#include <iostream>
using namespace std;

class Node{
    public:
        Node(int _x):x(_x){
            cout<<"construct"<<endl;
        }
        void *operator new(size_t size){
            cout<<"this is Node's operator new"<<endl;
            return ::operator new(size);//如果不調用全局的,可以改爲malloc(size)
        }
    private:
        int x;
};
int main(){
    Node *p = new Node(10);
    delete p;
}

輸出:


3. placement new

    placement new 是重載operator new 的一個標準、全局的版本,它不能被自定義的版本代替。placement new 在已經取得的內存空間上進行對象的構造。placement new 構造的對象,需要顯示調用他們的析構函數來銷燬。

使用步驟:

  1. 有預先分配的內存(即可以是棧也可以是堆);
  2. 在其上構造對象;
  3. 對對象進行操作;
  4. 對象析構;
  5. 內存釋放;

優點:

  • 可以在已經取得內存上構造對象;
  • 使用new操作符分配內存需要在堆中查找足夠大的剩餘空間,操作可能很慢,空間不足可能會拋出異常。placement new 可以在已經取得內存上構造對象,不需要查找內存,分配時間快,不會拋出異常;

使用舉例:

#include <iostream>
using namespace std;

class Node{
    public:
        Node(int _x):x(_x){
            cout<<"construct"<<endl;
        }
        void display(){
            cout<<"x = "<<x<<endl;
        }
        ~Node(){
            cout<<"~Node()"<<endl;
        }
    private:
        int x;
};
int main(){
    char *buff = new char[sizeof(Node)];   //有預先分配的內存
    Node *p = new(buff) Node(10);          //在其上構造對象,會調用placement new
    p->display();                          //對對象進行操作
    p->~Node();                            //對象析構
    delete []buff;                         //內存釋放
}

Reference :

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章