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

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

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

new做了哪些:

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

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

operator new
(1)只分配所要求的空間,不調(diào)用相關(guān)對(duì)象的構(gòu)造函數(shù)。當(dāng)無(wú)法滿足所要求分配的空間時(shí),則
->如果有new_handler,則調(diào)用new_handler,否則
->如果沒(méi)要求不拋出異常(以nothrow參數(shù)表達(dá)),則執(zhí)行bad_alloc異常,否則
->返回0
(2)可以被重載
(3)重載時(shí),返回類(lèi)型必須聲明為void*
(4)重載時(shí),第一個(gè)參數(shù)類(lèi)型必須為表達(dá)要求分配空間的大?。ㄗ止?jié)),類(lèi)型為size_t
(5)重載時(shí),可以帶其它參數(shù)

opeartor new重載測(cè)試

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ù)呢?首先第一點(diǎn)當(dāng)然是因?yàn)閚ew作為一種操作符是不能被重載的,而作為new中重要的一環(huán):分配內(nèi)存,重載operatir new就變的一種必要的操作了。全局opeartor new在分配內(nèi)存時(shí),實(shí)際上也是對(duì)malloc的一層包裝,在進(jìn)行大量次數(shù)的內(nèi)存分配時(shí)容易出現(xiàn)內(nèi)存碎片的問(wèn)題,通過(guò)重載operator new函數(shù)可以自定的將內(nèi)存分配在獨(dú)立出來(lái)的一塊內(nèi)存區(qū)域,可以更高效率的實(shí)現(xiàn)內(nèi)存分配的管理,同時(shí)也可以有效減少內(nèi)存碎片化以及不易與管理的問(wèn)題。

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

placement new

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

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

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

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

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

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

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

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

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

Placement new使用步驟

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

第一步 緩存提前分配

有三種方式:

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

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

2.在棧上進(jìn)行分配

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

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

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

第二步:對(duì)象的分配

在剛才已分配的緩存區(qū)調(diào)用placement new來(lái)構(gòu)造一個(gè)對(duì)象。

Task *ptask = new (buf) Task

第三步:使用

按照普通方式使用分配的對(duì)象:

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

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

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

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

第五步:釋放

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

delete [] buf;

總結(jié):

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

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

參考文章:

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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

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

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

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

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

    C++的命名空間詳解

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

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

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

    c++快速排序詳解

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

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

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

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

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

    C語(yǔ)言算法練習(xí)之求二維數(shù)組最值問(wèn)題

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

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

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

最新評(píng)論

蒙自县| 随州市| 遂平县| 浑源县| 邵阳县| 金沙县| 德格县| 金昌市| 鹿邑县| 彭山县| 台东县| 莆田市| 读书| 焦作市| 松桃| 灯塔市| 公主岭市| 新和县| 台中县| 芜湖县| 沂水县| 石门县| 竹溪县| 钦州市| 赫章县| 涡阳县| 侯马市| 麻江县| 清远市| 肥城市| 合水县| 双桥区| 临安市| 甘南县| 安康市| 沅陵县| 临西县| 磐安县| 湾仔区| 进贤县| 柳江县|