只在堆上或只在栈上定义对象
生活随笔
收集整理的這篇文章主要介紹了
只在堆上或只在栈上定义对象
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
轉(zhuǎn)自:http://blog.csdn.net/g5dsk/article/details/4775144
代碼:
[cpp]?view plaincopyprint? class?OnlyHeapClass?? {?? public:?? ????OnlyHeapClass()?? ????{?? ????}?? ?? ????void?Destroy()?? ????{?? ????????delete?this;?//?等效于"OnlyHeapClass::~OnlyHeapClass();",?寫?? ?????????????????????//?成"OnlyHeapClass::~OnlyHeapClass();"更容易理?? ?????????????????????//?解public成員函數(shù)調(diào)用private析構(gòu)函數(shù).?? ????}?? ?? private:?? ????~OnlyHeapClass()?? ????{?? ????}?? };?? ?? int?main()?? {?? ????OnlyHeapClass?*pInst?=?new?OnlyHeapClass;?? ?? ????pInst?->Destroy();?//?如果類中沒有定義Destroy()函數(shù),?而在這里用"delete?pInst;"代?? ???????????????????????//?替"pInst->Destroy();",?則會報(bào)錯(cuò).?因?yàn)?#34;delete?pInst;"會去調(diào)?? ???????????????????????//?用類的析構(gòu)函數(shù),?而在類域外調(diào)用類的private成員函數(shù)必然會報(bào)錯(cuò).?? ?? ????return?0;?? }??
總結(jié):??把析構(gòu)函數(shù)定義為private訪問權(quán)限, 就可以保證只能在堆(heap)上創(chuàng)建(new)一個(gè)新的類對象.
????
??? 原因是C++是一個(gè)靜態(tài)綁定的語言. 在編譯過程中, 所有的非虛函數(shù)調(diào)用都必須分析完成. 即使是虛函數(shù), 也需檢查可訪問性. 因些, 當(dāng)在棧(stack)上生成對象時(shí), 對象會自動析構(gòu), 也就說析構(gòu)函數(shù)必須可以訪問. 而堆上生成對象, 由于析構(gòu)時(shí)機(jī)由程序員控制, 所以不一定需要析構(gòu)函數(shù). 保證了不能在棧上生成對象后, 需要證明能在堆上生成它. 這里OnlyHeapClass與一般對象唯一的區(qū)別在于它的析構(gòu)函數(shù)為私有, delete操作會調(diào)用析構(gòu)函數(shù), 所以不能編譯.
??? 那么如何釋放它呢? 答案也很簡單, 提供一個(gè)成員函數(shù), 完成delete操作. 在成員函數(shù)中, 析構(gòu)函數(shù)是可以訪問的, 當(dāng)然detele操作也是可以編譯通過. [cpp]?view plaincopyprint? void?OnlyHeapClass::Destroy()??? {??? ????delete?this;??? }???
??? 另外重載delete, new為私有可以達(dá)到要求對象創(chuàng)建于棧上的目的, 用placement new也可以創(chuàng)建在棧上. /?下面灰色字體系轉(zhuǎn)載幫助理解之用?/??
??? 上面已經(jīng)提到, 你決定禁止產(chǎn)生某種類型的堆對象, 這時(shí)你可以自己創(chuàng)建一個(gè)資源封裝類, 該類對象只能在棧中產(chǎn)生, 這樣就能在異常的情況下自動釋放封裝的資源. ??? 那么怎樣禁止產(chǎn)生堆對象了? 我們已經(jīng)知道, 產(chǎn)生堆對象的唯一方法是使用new操作, 如果我們禁止使用new不就行了么. 再進(jìn)一步, new操作執(zhí)行時(shí)會調(diào)用operator new, 而operator new是可以重載的. 方法有了, 就是使new operator為private, 為了對稱, 最好將operator delete也重載為private. 現(xiàn)在, 你也許又有疑問了, 難道創(chuàng)建棧對象不需要調(diào)用new嗎? 是的, 不需要, 因?yàn)閯?chuàng)建棧對象不需要搜索內(nèi)存, 而是直接調(diào)整堆棧指針, 將對象壓棧, 而operator new的主要任務(wù)是搜索合適的堆內(nèi)存, 為堆對象分配空間, 這在上面已經(jīng)提到過了. 好, 讓我們看看下面的示例代碼:??? ? #include <stdlib.h>?? // 需要用到C式內(nèi)存分配函數(shù)???
? class Resource ;?? // 代表需要被封裝的資源類???
? class NoHashObject???
? {???
? private:???
? Resource *ptr ; // 指向被封裝的資源???
? // ...? //其它數(shù)據(jù)成員?
??
? void*?? operator?? new(size_t?? size) //非嚴(yán)格實(shí)現(xiàn), 僅作示意之用???
? {???
? return malloc(size);???
? }?
??
? void operator delete(void* pp) //非嚴(yán)格實(shí)現(xiàn), 僅作示意之用???
? {???
? free(pp);???
? }
??
? public:???
? NoHashObject()???
? {???
? // 此處可以獲得需要封裝的資源, 并讓ptr指針指向該資源???
? ptr = new Resource();???
? }?
??
? ~NoHashObject()???
? {???
? delete ptr;?? // 釋放封裝的資源???
? }???
? };?????
????
??? NoHashObject現(xiàn)在就是一個(gè)禁止堆對象的類了, 如果你寫下如下代碼:????
????
? NoHashObject* fp = new NoHashObject(); // 編譯期錯(cuò)誤!???
? delete fp;?
????
??? 上面代碼會產(chǎn)生編譯期錯(cuò)誤. 好了, 現(xiàn)在你已經(jīng)知道了如何設(shè)計(jì)一個(gè)禁止堆對象的類了, 你也許和我一樣有這樣的疑問, 難道在類NoHashObject的定義不能改變的情況下, 就一定不能產(chǎn)生該類型的堆對象了嗎? 不, 還是有辦法的, 我稱之為“暴力破解法”. C++是如此地強(qiáng)大, 強(qiáng)大到你可以用它做你想做的任何事情. 這里主要用到的是技巧是指針類型的強(qiáng)制轉(zhuǎn)換.????
????
? int main()???
? {???
? char*?? temp?? =?? new?? char[sizeof(NoHashObject)]?? ;???
????
? //強(qiáng)制類型轉(zhuǎn)換, 現(xiàn)在ptr是一個(gè)指向NoHashObject對象的指針???
? NoHashObject*?? obj_ptr?? =?? (NoHashObject*)temp?? ;???
????
? temp?? =?? NULL?? ;?? //防止通過temp指針修改NoHashObject對象???
????
? //再一次強(qiáng)制類型轉(zhuǎn)換, 讓rp指針指向堆中NoHashObject對象的ptr成員???
? Resource*?? rp?? =?? (Resource*)obj_ptr?? ;???
????
? //初始化obj_ptr指向的NoHashObject對象的ptr成員???
? rp?? =?? new?? Resource()?? ;???
? //現(xiàn)在可以通過使用obj_ptr指針使用堆中的NoHashObject對象成員了???
? ...?? ...???
????
? delete?? rp?? ;//釋放資源???
? temp?? =?? (char*)obj_ptr?? ;???
? obj_ptr?? =?? NULL?? ;//防止懸掛指針產(chǎn)生???
? delete?? []?? temp?? ;//釋放NoHashObject對象所占的堆空間.??
????
??? return 0;????
? }???? ??? 上面的實(shí)現(xiàn)是麻煩的, 而且這種實(shí)現(xiàn)方式幾乎不會在實(shí)踐中使用, 但是我還是寫出來路, 因?yàn)槔斫馑? 對于我們理解C++內(nèi)存對象是有好處的. 對于上面的這么多強(qiáng)制類型轉(zhuǎn)換, 其最根本的是什么了? 我們可以這樣理解:????
????
??? 某塊內(nèi)存中的數(shù)據(jù)是不變的, 而類型就是我們戴上的眼鏡, 當(dāng)我們戴上一種眼鏡后, 我們就會用對應(yīng)的類型來解釋內(nèi)存中的數(shù)據(jù), 這樣不同的解釋就得到了不同的信息.????
????
??? 所謂強(qiáng)制類型轉(zhuǎn)換實(shí)際上就是換上另一副眼鏡后再來看同樣的那塊內(nèi)存數(shù)據(jù).????
????????
??? 另外要提醒的是, 不同的編譯器對對象的成員數(shù)據(jù)的布局安排可能是不一樣的, 比如, 大多數(shù)編譯器將NoHashObject的ptr指針成員安排在對象空間的頭4個(gè)字節(jié), 這樣才會保證下面這條語句的轉(zhuǎn)換動作像我們預(yù)期的那樣執(zhí)行:????
????
? Resource*?? rp?? =?? (Resource*)obj_ptr?? ;?????
????
??? 但是, 并不一定所有的編譯器都是如此.????
????
??? 既然我們可以禁止產(chǎn)生某種類型的堆對象, 那么可以設(shè)計(jì)一個(gè)類, 使之不能產(chǎn)生棧對象嗎? 當(dāng)然可以.????
????
??? 五.禁止產(chǎn)生棧對象???
????
??? 前面已經(jīng)提到了, 創(chuàng)建棧對象時(shí)會移動棧頂指針以“挪出”適當(dāng)大小的空間, 然后在這個(gè)空間上直接調(diào)用對應(yīng)的構(gòu)造函數(shù)以形成一個(gè)棧對象, 而當(dāng)函數(shù)返回時(shí), 會調(diào)用其析構(gòu)函數(shù)釋放這個(gè)對象, 然后再調(diào)整棧頂指針收回那塊棧內(nèi)存. 在這個(gè)過程中是不需要operator?? new/delete操作的, 所以將operator?? new/delete設(shè)置為private不能達(dá)到目的. 當(dāng)然從上面的敘述中, 你也許已經(jīng)想到了: 將構(gòu)造函數(shù)或析構(gòu)函數(shù)設(shè)為私有的, 這樣系統(tǒng)就不能調(diào)用構(gòu)造/析構(gòu)函數(shù)了, 當(dāng)然就不能在棧中生成對象了.????
????
??? 這樣的確可以, 而且我也打算采用這種方案. 但是在此之前, 有一點(diǎn)需要考慮清楚,那就是, 如果我們將構(gòu)造函數(shù)設(shè)置為私有, 那么我們也就不能用new來直接產(chǎn)生堆對象了, 因?yàn)閚ew在為對象分配空間后也會調(diào)用它的構(gòu)造函數(shù)啊. 所以, 我打算只將析構(gòu)函數(shù)設(shè)置為private. 再進(jìn)一步, 將析構(gòu)函數(shù)設(shè)為private除了會限制棧對象生成外, 還有其它影響嗎? 是的, 這還會限制繼承.????
????
??? 如果一個(gè)類不打算作為基類, 通常采用的方案就是將其析構(gòu)函數(shù)聲明為private.????
????
??? 為了限制棧對象, 卻不限制繼承, 我們可以將析構(gòu)函數(shù)聲明為protected, 這樣就兩全其美了. 如下代碼所示:????
????
? class?? NoStackObject???
? {???
? protected:???
? ~NoStackObject()?? {?? }???
? public:???
? void?? destroy()???
? {???
? delete?? this?? ;//調(diào)用保護(hù)析構(gòu)函數(shù)???
? }???
? };?????
????
??? 接著, 可以像這樣使用NoStackObject類:????
????
? NoStackObject*?? hash_ptr?? =?? new?? NoStackObject()?? ;???
? ...?? ...?? //對hash_ptr指向的對象進(jìn)行操作???
? hash_ptr->destroy()?? ;?????
????
??? 呵呵, 是不是覺得有點(diǎn)怪怪的, 我們用new創(chuàng)建一個(gè)對象, 卻不是用delete去刪除它, 而是要用destroy方法. 很顯然, 用戶是不習(xí)慣這種怪異的使用方式的. 所以, 我決定將構(gòu)造函數(shù)也設(shè)為private或protected. 這又回到了上面曾試圖避免的問題, 即不用new, 那么該用什么方式來生成一個(gè)對象了? 我們可以用間接的辦法完成, 即讓這個(gè)類提供一個(gè)static成員函數(shù)專門用于產(chǎn)生該類型的堆對象. (設(shè)計(jì)模式中的singleton模式就可以用這種方式實(shí)現(xiàn). )讓我們來看看:????
????
? class?? NoStackObject???
? {???
? protected:???
? NoStackObject()?? {?? }???
? ~NoStackObject()?? {?? }???
? public:???
? static?? NoStackObject*?? creatInstance()???
? {???
? return?? new?? NoStackObject()?? ;//調(diào)用保護(hù)的構(gòu)造函數(shù)???
? }???
? void?? destroy()???
? {???
? delete?? this?? ;//調(diào)用保護(hù)的析構(gòu)函數(shù)???
? }???
? };?????
????
??? 現(xiàn)在可以這樣使用NoStackObject類了:????
????
? NoStackObject*?? hash_ptr?? =?? NoStackObject::creatInstance()?? ;???
? ...?? ...?? //對hash_ptr指向的對象進(jìn)行操作???
? hash_ptr->destroy()?? ;???
? hash_ptr?? =?? NULL?? ;?? //防止使用懸掛指針?????
????
??? 現(xiàn)在感覺是不是好多了, 生成對象和釋放對象的操作一致了. ??
??? 原因是C++是一個(gè)靜態(tài)綁定的語言. 在編譯過程中, 所有的非虛函數(shù)調(diào)用都必須分析完成. 即使是虛函數(shù), 也需檢查可訪問性. 因些, 當(dāng)在棧(stack)上生成對象時(shí), 對象會自動析構(gòu), 也就說析構(gòu)函數(shù)必須可以訪問. 而堆上生成對象, 由于析構(gòu)時(shí)機(jī)由程序員控制, 所以不一定需要析構(gòu)函數(shù). 保證了不能在棧上生成對象后, 需要證明能在堆上生成它. 這里OnlyHeapClass與一般對象唯一的區(qū)別在于它的析構(gòu)函數(shù)為私有, delete操作會調(diào)用析構(gòu)函數(shù), 所以不能編譯.
??? 那么如何釋放它呢? 答案也很簡單, 提供一個(gè)成員函數(shù), 完成delete操作. 在成員函數(shù)中, 析構(gòu)函數(shù)是可以訪問的, 當(dāng)然detele操作也是可以編譯通過. [cpp]?view plaincopyprint?
析構(gòu)函數(shù)私有化的類的設(shè)計(jì)可以保證只能用new命令在堆(heap)中創(chuàng)建對象, 只能動態(tài)的去創(chuàng)建對象, 這樣可以自由的控制對象的生命周期. 但是, 這樣的類需要提供創(chuàng)建和撤銷的公共接口.?
??? 另外重載delete, new為私有可以達(dá)到要求對象創(chuàng)建于棧上的目的, 用placement new也可以創(chuàng)建在棧上.
[cpp]?view plaincopyprint?
四.禁止產(chǎn)生堆對象
??? 上面已經(jīng)提到, 你決定禁止產(chǎn)生某種類型的堆對象, 這時(shí)你可以自己創(chuàng)建一個(gè)資源封裝類, 該類對象只能在棧中產(chǎn)生, 這樣就能在異常的情況下自動釋放封裝的資源. ??? 那么怎樣禁止產(chǎn)生堆對象了? 我們已經(jīng)知道, 產(chǎn)生堆對象的唯一方法是使用new操作, 如果我們禁止使用new不就行了么. 再進(jìn)一步, new操作執(zhí)行時(shí)會調(diào)用operator new, 而operator new是可以重載的. 方法有了, 就是使new operator為private, 為了對稱, 最好將operator delete也重載為private. 現(xiàn)在, 你也許又有疑問了, 難道創(chuàng)建棧對象不需要調(diào)用new嗎? 是的, 不需要, 因?yàn)閯?chuàng)建棧對象不需要搜索內(nèi)存, 而是直接調(diào)整堆棧指針, 將對象壓棧, 而operator new的主要任務(wù)是搜索合適的堆內(nèi)存, 為堆對象分配空間, 這在上面已經(jīng)提到過了. 好, 讓我們看看下面的示例代碼:??? ? #include <stdlib.h>?? // 需要用到C式內(nèi)存分配函數(shù)???
? class Resource ;?? // 代表需要被封裝的資源類???
? class NoHashObject???
? {???
? private:???
? Resource *ptr ; // 指向被封裝的資源???
? // ...? //其它數(shù)據(jù)成員?
??
? void*?? operator?? new(size_t?? size) //非嚴(yán)格實(shí)現(xiàn), 僅作示意之用???
? {???
? return malloc(size);???
? }?
??
? void operator delete(void* pp) //非嚴(yán)格實(shí)現(xiàn), 僅作示意之用???
? {???
? free(pp);???
? }
??
? public:???
? NoHashObject()???
? {???
? // 此處可以獲得需要封裝的資源, 并讓ptr指針指向該資源???
? ptr = new Resource();???
? }?
??
? ~NoHashObject()???
? {???
? delete ptr;?? // 釋放封裝的資源???
? }???
? };?????
????
??? NoHashObject現(xiàn)在就是一個(gè)禁止堆對象的類了, 如果你寫下如下代碼:????
????
? NoHashObject* fp = new NoHashObject(); // 編譯期錯(cuò)誤!???
? delete fp;?
????
??? 上面代碼會產(chǎn)生編譯期錯(cuò)誤. 好了, 現(xiàn)在你已經(jīng)知道了如何設(shè)計(jì)一個(gè)禁止堆對象的類了, 你也許和我一樣有這樣的疑問, 難道在類NoHashObject的定義不能改變的情況下, 就一定不能產(chǎn)生該類型的堆對象了嗎? 不, 還是有辦法的, 我稱之為“暴力破解法”. C++是如此地強(qiáng)大, 強(qiáng)大到你可以用它做你想做的任何事情. 這里主要用到的是技巧是指針類型的強(qiáng)制轉(zhuǎn)換.????
????
? int main()???
? {???
? char*?? temp?? =?? new?? char[sizeof(NoHashObject)]?? ;???
????
? //強(qiáng)制類型轉(zhuǎn)換, 現(xiàn)在ptr是一個(gè)指向NoHashObject對象的指針???
? NoHashObject*?? obj_ptr?? =?? (NoHashObject*)temp?? ;???
????
? temp?? =?? NULL?? ;?? //防止通過temp指針修改NoHashObject對象???
????
? //再一次強(qiáng)制類型轉(zhuǎn)換, 讓rp指針指向堆中NoHashObject對象的ptr成員???
? Resource*?? rp?? =?? (Resource*)obj_ptr?? ;???
????
? //初始化obj_ptr指向的NoHashObject對象的ptr成員???
? rp?? =?? new?? Resource()?? ;???
? //現(xiàn)在可以通過使用obj_ptr指針使用堆中的NoHashObject對象成員了???
? ...?? ...???
????
? delete?? rp?? ;//釋放資源???
? temp?? =?? (char*)obj_ptr?? ;???
? obj_ptr?? =?? NULL?? ;//防止懸掛指針產(chǎn)生???
? delete?? []?? temp?? ;//釋放NoHashObject對象所占的堆空間.??
????
??? return 0;????
? }???? ??? 上面的實(shí)現(xiàn)是麻煩的, 而且這種實(shí)現(xiàn)方式幾乎不會在實(shí)踐中使用, 但是我還是寫出來路, 因?yàn)槔斫馑? 對于我們理解C++內(nèi)存對象是有好處的. 對于上面的這么多強(qiáng)制類型轉(zhuǎn)換, 其最根本的是什么了? 我們可以這樣理解:????
????
??? 某塊內(nèi)存中的數(shù)據(jù)是不變的, 而類型就是我們戴上的眼鏡, 當(dāng)我們戴上一種眼鏡后, 我們就會用對應(yīng)的類型來解釋內(nèi)存中的數(shù)據(jù), 這樣不同的解釋就得到了不同的信息.????
????
??? 所謂強(qiáng)制類型轉(zhuǎn)換實(shí)際上就是換上另一副眼鏡后再來看同樣的那塊內(nèi)存數(shù)據(jù).????
????????
??? 另外要提醒的是, 不同的編譯器對對象的成員數(shù)據(jù)的布局安排可能是不一樣的, 比如, 大多數(shù)編譯器將NoHashObject的ptr指針成員安排在對象空間的頭4個(gè)字節(jié), 這樣才會保證下面這條語句的轉(zhuǎn)換動作像我們預(yù)期的那樣執(zhí)行:????
????
? Resource*?? rp?? =?? (Resource*)obj_ptr?? ;?????
????
??? 但是, 并不一定所有的編譯器都是如此.????
????
??? 既然我們可以禁止產(chǎn)生某種類型的堆對象, 那么可以設(shè)計(jì)一個(gè)類, 使之不能產(chǎn)生棧對象嗎? 當(dāng)然可以.????
????
??? 五.禁止產(chǎn)生棧對象???
????
??? 前面已經(jīng)提到了, 創(chuàng)建棧對象時(shí)會移動棧頂指針以“挪出”適當(dāng)大小的空間, 然后在這個(gè)空間上直接調(diào)用對應(yīng)的構(gòu)造函數(shù)以形成一個(gè)棧對象, 而當(dāng)函數(shù)返回時(shí), 會調(diào)用其析構(gòu)函數(shù)釋放這個(gè)對象, 然后再調(diào)整棧頂指針收回那塊棧內(nèi)存. 在這個(gè)過程中是不需要operator?? new/delete操作的, 所以將operator?? new/delete設(shè)置為private不能達(dá)到目的. 當(dāng)然從上面的敘述中, 你也許已經(jīng)想到了: 將構(gòu)造函數(shù)或析構(gòu)函數(shù)設(shè)為私有的, 這樣系統(tǒng)就不能調(diào)用構(gòu)造/析構(gòu)函數(shù)了, 當(dāng)然就不能在棧中生成對象了.????
????
??? 這樣的確可以, 而且我也打算采用這種方案. 但是在此之前, 有一點(diǎn)需要考慮清楚,那就是, 如果我們將構(gòu)造函數(shù)設(shè)置為私有, 那么我們也就不能用new來直接產(chǎn)生堆對象了, 因?yàn)閚ew在為對象分配空間后也會調(diào)用它的構(gòu)造函數(shù)啊. 所以, 我打算只將析構(gòu)函數(shù)設(shè)置為private. 再進(jìn)一步, 將析構(gòu)函數(shù)設(shè)為private除了會限制棧對象生成外, 還有其它影響嗎? 是的, 這還會限制繼承.????
????
??? 如果一個(gè)類不打算作為基類, 通常采用的方案就是將其析構(gòu)函數(shù)聲明為private.????
????
??? 為了限制棧對象, 卻不限制繼承, 我們可以將析構(gòu)函數(shù)聲明為protected, 這樣就兩全其美了. 如下代碼所示:????
????
? class?? NoStackObject???
? {???
? protected:???
? ~NoStackObject()?? {?? }???
? public:???
? void?? destroy()???
? {???
? delete?? this?? ;//調(diào)用保護(hù)析構(gòu)函數(shù)???
? }???
? };?????
????
??? 接著, 可以像這樣使用NoStackObject類:????
????
? NoStackObject*?? hash_ptr?? =?? new?? NoStackObject()?? ;???
? ...?? ...?? //對hash_ptr指向的對象進(jìn)行操作???
? hash_ptr->destroy()?? ;?????
????
??? 呵呵, 是不是覺得有點(diǎn)怪怪的, 我們用new創(chuàng)建一個(gè)對象, 卻不是用delete去刪除它, 而是要用destroy方法. 很顯然, 用戶是不習(xí)慣這種怪異的使用方式的. 所以, 我決定將構(gòu)造函數(shù)也設(shè)為private或protected. 這又回到了上面曾試圖避免的問題, 即不用new, 那么該用什么方式來生成一個(gè)對象了? 我們可以用間接的辦法完成, 即讓這個(gè)類提供一個(gè)static成員函數(shù)專門用于產(chǎn)生該類型的堆對象. (設(shè)計(jì)模式中的singleton模式就可以用這種方式實(shí)現(xiàn). )讓我們來看看:????
????
? class?? NoStackObject???
? {???
? protected:???
? NoStackObject()?? {?? }???
? ~NoStackObject()?? {?? }???
? public:???
? static?? NoStackObject*?? creatInstance()???
? {???
? return?? new?? NoStackObject()?? ;//調(diào)用保護(hù)的構(gòu)造函數(shù)???
? }???
? void?? destroy()???
? {???
? delete?? this?? ;//調(diào)用保護(hù)的析構(gòu)函數(shù)???
? }???
? };?????
????
??? 現(xiàn)在可以這樣使用NoStackObject類了:????
????
? NoStackObject*?? hash_ptr?? =?? NoStackObject::creatInstance()?? ;???
? ...?? ...?? //對hash_ptr指向的對象進(jìn)行操作???
? hash_ptr->destroy()?? ;???
? hash_ptr?? =?? NULL?? ;?? //防止使用懸掛指針?????
????
??? 現(xiàn)在感覺是不是好多了, 生成對象和釋放對象的操作一致了. ??
總結(jié)
以上是生活随笔為你收集整理的只在堆上或只在栈上定义对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。