欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++中的opeartor?new和placement?new使用步驟

 更新時間:2022年10月18日 13:11:49   作者:Z.0103  
這篇文章主要介紹了C++中的opeartor?new和placement?new詳解,在很多情況下,placement?new的使用方法和其他普通的new有所不同。這里提供了它的使用步驟,需要的朋友可以參考下

new做了哪些:

在c++中,對new的調(diào)用時,new完成的工作通常是有以下幾步:

調(diào)用operator new函數(shù)分配出內(nèi)存待用對象的構造方法構造出對象返回該對象的指針

operator new
(1)只分配所要求的空間,不調(diào)用相關對象的構造函數(shù)。當無法滿足所要求分配的空間時,則
->如果有new_handler,則調(diào)用new_handler,否則
->如果沒要求不拋出異常(以nothrow參數(shù)表達),則執(zhí)行bad_alloc異常,否則
->返回0
(2)可以被重載
(3)重載時,返回類型必須聲明為void*
(4)重載時,第一個參數(shù)類型必須為表達要求分配空間的大小(字節(jié)),類型為size_t
(5)重載時,可以帶其它參數(shù)

opeartor new重載測試

class X
{
public:
    X() { cout<<"constructor of X"<<endl;}
    ~X() { cout<<"destructor of X"<<endl;}
    void* operator new(size_t size,string str)
    {
        cout<<"operator new size "<<size<<" with string "<<str<<endl;
        return ::operator new(size);
    }

    void operator delete(void* pointee)
    {
        cout<<"operator delete"<<endl;
        ::operator delete(pointee);		//調(diào)用全局的 operator delete函數(shù)
    }
private:
    int num;
};

int main()
{
    X *px = new("A new") X;
    delete px;
    return 0;
}

// 輸出結果
// operator new size 4 with string A new
// constructor of X
// destructor of X
// operator delete

那么為什么要重載operator new函數(shù)呢?首先第一點當然是因為new作為一種操作符是不能被重載的,而作為new中重要的一環(huán):分配內(nèi)存,重載operatir new就變的一種必要的操作了。全局opeartor new在分配內(nèi)存時,實際上也是對malloc的一層包裝,在進行大量次數(shù)的內(nèi)存分配時容易出現(xiàn)內(nèi)存碎片的問題,通過重載operator new函數(shù)可以自定的將內(nèi)存分配在獨立出來的一塊內(nèi)存區(qū)域,可以更高效率的實現(xiàn)內(nèi)存分配的管理,同時也可以有效減少內(nèi)存碎片化以及不易與管理的問題。

重載operator new函數(shù)還有很多的用途,比如,他可以幫助我們查找內(nèi)存泄漏,在c++中,內(nèi)存泄漏是痛中之痛,重載該函數(shù)并與宏定義相配合可以很好的檢測出內(nèi)存泄漏的地方在哪里。相關文章鏈接:http://www.dbjr.com.cn/article/41939.htm

placement new

placement new是operator new的一個重載版本,他的作用是可以將一個對象分配到指定的內(nèi)存空間。實現(xiàn)代碼如下:

void* operator new(std::size_t, void* __p) throw()
{
    return __p;
}

placement new 只是operator new的一個重載版本,只是起了一個別名而已.
代碼示例:

class A{
    int num;
public:
    A(){
        cout<<"A's constructor"<<endl;
    }

    ~A(){
        cout<<"~A"<<endl;
    }
    void show(){
        cout<<"num:"<<num<<endl;
    }
};


int main()
{
	char* mem;
	cout << (void*)mem << endl;
	A* a = new(mem) A;
	cout << (void*)a << endl;
	return 0;
}

// 0x104e570ac
// A's constructor
// 0x104e570ac

閱讀以上程序,注意以下幾點。
(1)用定位放置new操作,既可以在棧(stack)上生成對象,也可以在堆(heap)上生成對象。如本例就是在棧上生成一個對象。

(2)使用語句A* p=new (mem) A;定位生成對象時,指針p和數(shù)組名mem指向同一片存儲區(qū)。所以,與其說定位放置new操作是申請空間,還不如說是利用已經(jīng)請好的空間,真正的申請空間的工作是在此之前完成的。

(3)使用語句A *p=new (mem) A;定位生成對象是,會自動調(diào)用類A的構造函數(shù),但是由于對象的空間不會自動釋放(對象實際上是借用別人的空間),所以必須顯示的調(diào)用類的析構函數(shù),如本例中的p->~A()。

(4)萬不得已才使用placement new,只有當你真的在意對象在內(nèi)存中的特定位置時才使用它。例如,你的硬件有一個內(nèi)存映像的I/O記時器設備,并且你想放置一個Clock對象在哪那個位置。

在一些高效率的程序中,往往會開辟出一塊獨立的內(nèi)存空間配合placement new來實現(xiàn)高效率的內(nèi)存釋放與配置,如在SGI STL的內(nèi)存配置函數(shù)allocate 與 deallcate函數(shù),以及大名鼎鼎的memory pool技術都很大程度上依靠了placement new定位創(chuàng)建對象。在快速的內(nèi)存分配與釋放的過程中這是一個非常實用的方法。

Placement new使用步驟

在很多情況下,placement new的使用方法和其他普通的new有所不同。這里提供了它的使用步驟。

第一步 緩存提前分配

有三種方式:

1.為了保證通過placement new使用的緩存區(qū)的memory alignment(內(nèi)存隊列)正確準備,使用普通的new來分配它:在堆上進行分配

class Task ;
char * buff = new [sizeof(Task)]; //分配內(nèi)存
(請注意auto或者static內(nèi)存并非都正確地為每一個對象類型排列,所以,你將不能以placement new使用它們。)

2.在棧上進行分配

class Task ;
char buf[N*sizeof(Task)]; //分配內(nèi)存

3.還有一種方式,就是直接通過地址來使用。(必須是有意義的地址)

void* buf = reinterpret_cast<void*> (0xF00F);

第二步:對象的分配

在剛才已分配的緩存區(qū)調(diào)用placement new來構造一個對象。

Task *ptask = new (buf) Task

第三步:使用

按照普通方式使用分配的對象:

ptask->memberfunction();
ptask-> member;
//...

第四步:對象的析構

一旦你使用完這個對象,你必須調(diào)用它的析構函數(shù)來毀滅它。按照下面的方式調(diào)用析構函數(shù):

ptask->~Task(); //調(diào)用外在的析構函數(shù),顯式調(diào)用!

第五步:釋放

你可以反復利用緩存并給它分配一個新的對象(重復步驟2,3,4)如果你不打算再次使用這個緩存,你可以象這樣釋放它:

delete [] buf;

總結:

(1)若想在堆上建立一個對象,應該用new操作符。它既分配內(nèi)存又調(diào)用其構造函數(shù)進行初始化。
(2)若僅僅想分配內(nèi)存,應該調(diào)用operator new(),他不會調(diào)用構造函數(shù)。若想定制自己在堆對象被建立時的內(nèi)存分配過程,應該重寫自己的operator new()。
(3)若想在一塊已經(jīng)獲得的內(nèi)存空間上建立一個對象,應該用placement new。在實際開發(fā)過程中,這種寫法一般在高性能高穩(wěn)定場景下使用。本文主要是為了更好的理解STL源碼中alloator的內(nèi)存管理行為所寫。

理解可能并不規(guī)范,表達也會有所紕漏。

參考文章:

https://cloud.tencent.com/developer/article/1177460

https://blog.51cto.com/u_15060533/4689267

https://www.cnblogs.com/luxiaoxun/archive/2012/08/10/2631812.html

到此這篇關于C++中的opeartor new和placement new詳解的文章就介紹到這了,更多相關C++ opeartor new和placement new內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Qt學習筆記之QPalette調(diào)色板類

    Qt學習筆記之QPalette調(diào)色板類

    這篇文章主要為大家詳細介紹了Qt學習筆記之QPalette調(diào)色板類,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • C++中調(diào)用復制(拷貝)函數(shù)的三種情況總結

    C++中調(diào)用復制(拷貝)函數(shù)的三種情況總結

    這篇文章主要介紹了C++中調(diào)用復制(拷貝)函數(shù)的三種情況總結,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++?STL容器與函數(shù)謂詞示例分析講解

    C++?STL容器與函數(shù)謂詞示例分析講解

    這篇文章主要介紹了C++?STL容器與函數(shù)謂詞示例,STL是“Standard?Template?Library”的縮寫,中文譯為“標準模板庫”。STL是C++標準庫的一部分,不用單獨安裝
    2022-11-11
  • 零基礎詳解C語言指針進階

    零基礎詳解C語言指針進階

    在C語言和C++等語言中,數(shù)組元素全為指針變量的數(shù)組稱為指針數(shù)組,指針數(shù)組中的元素都必須具有相同的存儲類型、指向相同數(shù)據(jù)類型的指針變量。指針數(shù)組比較適合用來指向若干個字符串,使字符串處理更加方便、靈活
    2022-02-02
  • C++私有繼承(三)

    C++私有繼承(三)

    這篇文章主要介紹了C++私有繼承(三),前面的文章我們已經(jīng)介紹過了C++私有繼承(一)和(二),下面小編就繼續(xù)基于之前的內(nèi)容繼續(xù)向大家介紹C++私有繼承,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-02-02
  • C++可以函數(shù)重載而C不可以的原因分析

    C++可以函數(shù)重載而C不可以的原因分析

    函數(shù)重載是指在同一個作用域內(nèi),可以定義多個函數(shù),它們具有相同的名稱但是參數(shù)列表不同,為什么C++可以函數(shù)重載而C不可以,接下來就有小編來給大家介紹一下C++可以函數(shù)重載而C不可以的原因,需要的朋友可以參考下
    2023-12-12
  • C++實現(xiàn)模板中的非類型參數(shù)的方法

    C++實現(xiàn)模板中的非類型參數(shù)的方法

    這篇文章主要介紹了C++實現(xiàn)模板中的非類型參數(shù)的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • C語言冒泡排序算法代碼詳解

    C語言冒泡排序算法代碼詳解

    大家好,本篇文章主要講的是C語言冒泡排序算法代碼詳解,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • c++中for雙循環(huán)的那些事

    c++中for雙循環(huán)的那些事

    本人很菜,今天看《C++編程思想》中的一道課后題中說到這樣一個問題。修改兩層嵌套的for循環(huán)的標識符,觀察結果變化
    2013-05-05
  • C++繼承的定義與注意事項

    C++繼承的定義與注意事項

    這篇文章主要給大家介紹了關于C++繼承的定義與注意事項的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05

最新評論