小結:c++中的new、operator new和placement new

c++中的new、operator new和placement new

1、new

  • new(也稱做new operator),是new 操做符,不可重載
class T{...};
T *t = new T(initial_args_list); //此時的new ,是new 操做符

new操做 會執行如下三個步驟ios

  1. 調用類的(若是重載了的話)或者全局的operator new分配空間
  2. 用類型後面列的參數列表來調用構造函數,生成類對象
  3. 返回對應的指針

2、 operator new

  • operator new是 operator 函數,與operator +等函數相似,能夠被重載,operator new通常在類中進行重載。在全局重載容易形成程序崩潰,由於全局的::operator new 負責整個程序運行期間的堆空間的分配,重載全局::operator new 須慎之又慎!

例:c++

class T{
    ...
    void* operator new(size_t){
    ... //自定義操做
      return ::operator new(size_t);
  }
};

3、placement new

  • 是重載operator new 的一個標準、全局的版本緩存

  • 它不可以被自定義的版本代替,即不能重載。它的做用是在已分配的空間中構造對象。函數

void *operator new( size_t, void * p ) throw() { return p; }

Placement new使用步驟學習

在不少狀況下,placement new的使用方法和其餘普通的new有所不一樣。這裏提供了它的使用步驟。spa

  • 緩存提早分配
char*buf = (::operator new((size_t)(sizeof(T))));
  • 對象的分配,在已分配的緩存中調用構造函數,生成對象
T *t = new(buf)T;
  • 使用對象,用-> 訪問對象的成員
t->men_func();
  • 調用外在的析構函數
t->~T();
  • 釋放資源
delete [] buf;

使用例子:

#include <stdio.h>
#include <iostream>
#include <string>
#include <malloc.h>
using namespace std;


class testNew{
public:
    testNew(){ cout << "執行了testNew::testNew() 構造函數" << endl; }
    ~testNew(){ cout << "執行了testNew::~testNew() 析構函數" << endl; }

    void* operator new(size_t size, string str){
        cout << "重載1:testNew::op new," << str << endl;
        return ::operator new(size);
    }

    void* operator new(size_t size){
        cout << "  重載2:testNe  w::op new,without str"  << endl;
        return ::operator new(size);
    }
    void print(){
        cout << "已初始化成功" << endl;
    }

};

void * operator new(size_t size)
{
    cout << "::op new 內存分配 "<< endl;
    return malloc(size);
}


int main()
{
    
    cout << "重載全局 ::op new" << endl;
    char * buf = (char *)(::operator new((size_t)(sizeof(testNew))));
    cout << endl;

    cout << " placement new" << endl;
    //不加::,會調用 void* testNew:: operator new(size_t size, string str)
    //致使不能匹配全局的placement new
    testNew *test = ::new (buf)testNew;
    test->print();
    test->~testNew();
    delete []buf;
    cout << endl;

    cout << " 重載 testNew::op new 1" << endl;
    //此時輸出有4行
    testNew *test2 = new("with str")testNew;

    //::op new 內存分配                -> 給const char* "重載"分配堆空間
    //重載1:testNew::op new,with str  ->調用testNew::op new 1
    //::op new 內存分配                ->testNew::op new 1調用 全局的 ::op new
    //執行了testNew::testNew() 構造函數 
    
    test2->print();               //輸出 「已初始化成功」 ,表示已正確返回指針
    cout << endl;


    cout << " 重載 testNew::op new 2" << endl;
    testNew *test3 = new testNew;
    test3->print();               //輸出 「已初始化成功」 ,表示已正確返回指針
    cout << endl;


    cout << "析構" << endl;
    delete test2;
    delete test3;

    getchar();
    return 0;

}

  • 原創全部,轉載註明出處,如有錯誤,歡迎你們指正,共同窗習。謝謝!
相關文章
相關標籤/搜索