最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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)存待用對象的構(gòu)造方法構(gòu)造出對象返回該對象的指針

operator new
(1)只分配所要求的空間,不調(diào)用相關(guān)對象的構(gòu)造函數(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;
}

// 輸出結(jié)果
// 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)存泄漏的地方在哪里。相關(guān)文章鏈接:http://m.fzitv.net/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的構(gòu)造函數(shù),但是由于對象的空間不會自動釋放(對象實際上是借用別人的空間),所以必須顯示的調(diào)用類的析構(gòu)函數(shù),如本例中的p->~A()。

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

在一些高效率的程序中,往往會開辟出一塊獨立的內(nèi)存空間配合placement new來實現(xiàn)高效率的內(nèi)存釋放與配置,如在SGI STL的內(nèi)存配置函數(shù)allocate 與 deallcate函數(shù),以及大名鼎鼎的memory pool技術(shù)都很大程度上依靠了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來構(gòu)造一個對象。

Task *ptask = new (buf) Task

第三步:使用

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

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

第四步:對象的析構(gòu)

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

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

第五步:釋放

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

delete [] buf;

總結(jié):

(1)若想在堆上建立一個對象,應(yīng)該用new操作符。它既分配內(nèi)存又調(diào)用其構(gòu)造函數(shù)進行初始化。
(2)若僅僅想分配內(nèi)存,應(yīng)該調(diào)用operator new(),他不會調(diào)用構(gòu)造函數(shù)。若想定制自己在堆對象被建立時的內(nèi)存分配過程,應(yīng)該重寫自己的operator new()。
(3)若想在一塊已經(jīng)獲得的內(nèi)存空間上建立一個對象,應(yīng)該用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

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

相關(guān)文章

  • C/C++中多重繼承詳解及其作用介紹

    C/C++中多重繼承詳解及其作用介紹

    這篇文章主要介紹了C/C++中多重繼承詳解及其作用介紹,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • C++中delete指針后最好將其置空的操作方法

    C++中delete指針后最好將其置空的操作方法

    C++編程中,當你使用delete運算符釋放指針所指向的內(nèi)存后,通常將該指針置空,如果一個指針在被刪除后沒有置空,而你在代碼的其他部分再次嘗試刪除同一個指針,可能會導致程序崩潰或產(chǎn)生未定義行為,本文介紹C++中delete指針后最好將其置空的操作方法,感興趣的朋友一起看看吧
    2024-06-06
  • C++雙向鏈表實現(xiàn)簡單通訊錄

    C++雙向鏈表實現(xiàn)簡單通訊錄

    這篇文章主要為大家詳細介紹了C++雙向鏈表實現(xiàn)簡單通訊錄,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C++的命名空間詳解

    C++的命名空間詳解

    這篇文章主要介紹了C++編程中的命名空間基本知識講解,包括對C++中內(nèi)聯(lián)命名空間新特性的介紹,需要的朋友可以參考下
    2021-09-09
  • C++ 基數(shù)排序的實現(xiàn)實例代碼

    C++ 基數(shù)排序的實現(xiàn)實例代碼

    這篇文章主要介紹了C++ 基數(shù)排序的實現(xiàn)實例代碼的相關(guān)資料,這里附有實例代碼,幫助大家學習理解,需要的朋友可以參考下
    2016-11-11
  • c++快速排序詳解

    c++快速排序詳解

    快速排序總體思想:先找到一個樞軸,讓他作為分水嶺,通過一趟排序?qū)⒋判虻挠涗浄指畛蓛刹糠?前面一部分都比樞軸小,后面一部分樞軸大,然后又分別對這兩部分記錄繼續(xù)進行遞歸的排序,達到整個序列有序的目的
    2017-05-05
  • 一道超經(jīng)典的C++結(jié)構(gòu)體的題目

    一道超經(jīng)典的C++結(jié)構(gòu)體的題目

    以下小編就為大家介紹一道超經(jīng)典的關(guān)于C++結(jié)構(gòu)體的題目。需要的朋友可以過來參考下
    2013-09-09
  • 詳解C語言內(nèi)核中的自旋鎖結(jié)構(gòu)

    詳解C語言內(nèi)核中的自旋鎖結(jié)構(gòu)

    自旋鎖是內(nèi)核中提供的一種高IRQL鎖,用同步以及獨占的方式訪問某個資源。自旋鎖是為了解決內(nèi)核鏈表讀寫時存在線程同步問題。本文將講解一下自旋鎖的簡單應(yīng)用,感興趣的可以了解一下
    2022-09-09
  • C語言算法練習之求二維數(shù)組最值問題

    C語言算法練習之求二維數(shù)組最值問題

    這篇文章主要為大家介紹了C語言算法練習中求二維數(shù)組最值的實現(xiàn)方法,文中的示例代碼講解詳細,對我們學習C語言有一定幫助,需要的可以參考一下
    2022-09-09
  • 對比分析C語言中的gcvt()和ecvt()以及fcvt()函數(shù)

    對比分析C語言中的gcvt()和ecvt()以及fcvt()函數(shù)

    這篇文章主要介紹了對比分析C語言中的gcvt和ecvt以及fcvt函數(shù),都是將數(shù)字轉(zhuǎn)化為字符串,注意其之間的功能區(qū)別,需要的朋友可以參考下
    2015-08-08

最新評論

德格县| 陵川县| 沅陵县| 改则县| 汝南县| 高清| 小金县| 车险| 徐水县| 金平| 金乡县| 蒙阴县| 德清县| 青田县| 上思县| 龙泉市| 墨竹工卡县| 文成县| 黄陵县| 开平市| 南川市| 缙云县| 邓州市| 上栗县| 白河县| 太和县| 阆中市| 辽源市| 木兰县| 綦江县| 钟山县| 金川县| 正阳县| 木兰县| 射阳县| 清流县| 青浦区| 弋阳县| 故城县| 阜新市| 揭西县|