如何定義一個只能在堆上(棧上)生成對象的類?

在C++中,類的對象建立分為兩種,一種是靜態建立,如A a;另一種是動態建立,如A* ptr=new A;這兩種方式是有區別的。

? ? ? ? 靜態建立一個類對象,是由編譯器為對象在棧空間中分配內存,是通過直接移動棧頂指針,挪出適當的空間,然后在這片內存空間上調用構造函數形成一個棧對象。使用這種方法,直接調用類的構造函數。

? ? ? ? 動態建立類對象,是使用new運算符將對象建立在堆空間中。這個過程分為兩步,第一步是執行operator new()函數,在堆空間中搜索合適的內存并進行分配;第二步是調用構造函數構造對象,初始化這片內存空間。這種方法,間接調用類的構造函數。

? ? ? ? 那么如何限制類對象只能在堆或者棧上建立呢?下面分別進行討論。

?

1、只能建立在堆上

? ? ? ? 類對象只能建立在堆上,就是不能靜態建立類對象,即不能直接調用類的構造函數。

? ? ? ? 容易想到將構造函數設為私有。在構造函數私有之后,無法在類外部調用構造函數來構造類對象,只能使用new運算符來建立對象。然而,前面已經說過,new運算符的執行過程分為兩步,C++提供new運算符的重載,其實是只允許重載operator new()函數,而operator()函數用于分配內存,無法提供構造功能。因此,這種方法不可以。

? ? ? ? 當對象建立在棧上面時,是由編譯器分配內存空間的,調用構造函數來構造棧對象。當對象使用完后,編譯器會調用析構函數來釋放棧對象所占的空間。編譯器管理了對象的整個生命周期。如果編譯器無法調用類的析構函數,情況會是怎樣的呢?比如,類的析構函數是私有的,編譯器無法調用析構函數來釋放內存。所以,編譯器在為類對象分配棧空間時,會先檢查類的析構函數的訪問性,其實不光是析構函數,只要是非靜態的函數,編譯器都會進行檢查。如果類的析構函數是私有的,則編譯器不會在棧空間上為類對象分配內存。

? ? ? ? 因此,將析構函數設為私有,類對象就無法建立在棧上了。代碼如下:

[cpp]?view plaincopyprint?
  1. class??A??
  2. {??
  3. public?:??
  4. ????A(){}??
  5. ????void??destory(){?delete???this?;}??
  6. private?:??
  7. ????~A(){}??
  8. };??

? ? ? ? 試著使用A a;來建立對象,編譯報錯,提示析構函數無法訪問。這樣就只能使用new操作符來建立對象,構造函數是公有的,可以直接調用。類中必須提供一個destory函數,來進行內存空間的釋放。類對象使用完成后,必須調用destory函數。

? ? ? ? 上述方法的一個缺點就是,無法解決繼承問題。如果A作為其它類的基類,則析構函數通常要設為virtual,然后在子類重寫,以實現多態。因此析構函數不能設為private。還好C++提供了第三種訪問控制,protected。將析構函數設為protected可以有效解決這個問題,類外無法訪問protected成員,子類則可以訪問。

? ? ? ? 另一個問題是,類的使用很不方便,使用new建立對象,卻使用destory函數釋放對象,而不是使用delete。(使用delete會報錯,因為delete對象的指針,會調用對象的析構函數,而析構函數類外不可訪問)這種使用方式比較怪異。為了統一,可以將構造函數設為protected,然后提供一個public的static函數來完成構造,這樣不使用new,而是使用一個函數來構造,使用一個函數來析構。代碼如下,類似于單例模式:

[cpp]?view plaincopyprint?
  1. class??A??
  2. {??
  3. protected?:??
  4. ????A(){}??
  5. ????~A(){}??
  6. public?:??
  7. ????static??A*?create()??
  8. ????{??
  9. ????????return???new??A();??
  10. ????}??
  11. ????void??destory()??
  12. ????{??
  13. ????????delete???this?;??
  14. ????}??
  15. };??

? ? ? ? 這樣,調用create()函數在堆上創建類A對象,調用destory()函數釋放內存。

?

2、只能建立在棧上

? ? ? ? 只有使用new運算符,對象才會建立在堆上,因此,只要禁用new運算符就可以實現類對象只能建立在棧上。將operator new()設為私有即可。代碼如下:

[cpp]?view plaincopyprint?
  1. class??A??
  2. {??
  3. private?:??
  4. ????void?*?operator??new?(?size_t??t){}??????//?注意函數的第一個參數和返回值都是固定的???
  5. ????void??operator??delete?(?void?*?ptr){}??//?重載了new就需要重載delete???
  6. public?:??
  7. ????A(){}??
  8. ????~A(){}??
  9. };?

?

參考資料:

  1.?http://www.nowcoder.com/questionTerminal/0a584aa13f804f3ea72b442a065a7618

轉載于:https://www.cnblogs.com/vincently/p/4838283.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458834.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458834.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458834.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

canny算子的理論分析

****************************************************************************************************************************************** 紅:數字圖像處理視頻教程(兩部) {中科院版36講視頻教程 電子科大版70講視頻教程&#x…

Android為spinner設置適配器,Android Spinner與適配器模式詳解及實例代碼

最近做項目對Android Spinner 使用,這里簡單寫個小例子,來測試如何使用。Spinner是一個下拉列表,往安卓界面中拖拽一個Spinner控件,在屬性中設置Android:entries“array/spinner_data”其中spinner_data為在string中設置的數組。數…

web框架-Struts開始

問題: 為什么有structs 作為一種框架(frameset)可以與傳統的mvc進行比較? MVC是一種模式數據處理、顯示和數據輸入分開,來規范開發,但是卻又并不規范。可以這樣想:有三家公司,他們對…

加快上架方法

估計最近蘋果app應用上架的比較多,審核比較慢,現在一個app從提交到上架短則7,8天,長則2,3個星期。我在實際上線應用時,總結了一個簡單實用的小技巧,可以加快上架時間,最近使用這種方…

接口自動化測試 返回html,接口自動化測試實戰(更新完畢)

前言自動化沒練習的項目怎么辦?自動化已經成為測試的必備技能之一了,所以,很多想跳槽的測試朋友都在自學,特別是最實用的接口自動化,但是很多人因為沒有可以練手的項目而苦惱,最終導致缺乏實戰經驗&#xf…

Opencv 圖像增強算法 圖像檢測結果及代碼

****************************************************************************************************************************************** 紅:數字圖像處理視頻教程(兩部) {中科院版36講視頻教程 電子科大版70講視頻教程&#x…

php Hash Table(四) Hash Table添加和更新元素

HashTable添加和更新的函數: 有4個主要的函數用于插入和更新HashTable的數據: int zend_hash_add(HashTable *ht, char *arKey, uint nKeyLen,void **pData, uint nDataSize, void *pDest); int zend_hash_update(HashTable *ht, char *arKey, uint nKeyLen, void …

山寨“餓了么”應用中添加菜品數量按鈕效果

山寨“餓了么”應用中添加菜品數量按鈕效果 本人視頻教程系類 iOS中CALayer的使用 最終效果: 山寨源頭: 源碼:(此源碼解決了重用問題,可以放心的放在cell中使用) AddAndDeleteButton.h 與 AddAndDeleteBu…

html間數據傳送,Express框架與html之間如何進行數據傳遞(示例代碼)

關于Node.js 的Express框架介紹,推薦看菜鳥教程的Express框架,很適合入門,這里不再贅述,這里主要講一下Express框架與html之間如何進行數據傳遞我采用的是JQuery的Ajax()向后臺傳參方式(url傳參)1、Type屬性為Get時:(1…

數字圖像去噪典型算法及matlab實現

圖像去噪是數字圖像處理中的重要環節和步驟。去噪效果的好壞直接影響到后續的圖像處理工作如圖像分割、邊緣檢測等。圖像信號在產生、傳輸過程中都可能會受到噪聲的污染,一般數字圖像系統中的常見噪聲主要有:高斯噪聲(主要由阻性元器件內部產…

pat1100. Mars Numbers (20)

1100. Mars Numbers (20) 時間限制400 ms內存限制65536 kB代碼長度限制16000 B判題程序Standard 作者CHEN, YuePeople on Mars count their numbers with base 13: Zero on Earth is called "tret" on Mars.The numbers 1 to 12 on Earch is called "jan, feb, …

【USACO1.1】Broken Necklace

題意 一個環形項鏈,有rbw三種珠子,r代表red,b代表blue,w代表white,從任意一個位置斷開,兩端分別取珠子,同一端取的珠子要相同顏色,w可以染成想要的顏色,即既可當作r也可以…

html+注釋格式化,使用xml注釋來生成格式化的html輸出

我試圖從我在xml文件中的注釋中生成一個格式良好的html文檔。目前我有一個xml文件,用于生成xml表格的html列表。為了讓我添加有關表格的評論,我手動將注釋添加到輸出html文件中。使用xml注釋來生成格式化的html輸出我想如果可能將html代碼放在xml文件中作…

圖像增強-圖像銳化

圖像銳化主要影響圖像中的低頻分量,不影響圖像中的高頻分量。 圖像銳化的主要目的有兩個: 1.增強圖像邊緣,使模糊的圖像變得更加清晰,顏色變得鮮明突出,圖像的質量有所改善,產生更適合人眼觀察和識別的圖像…

[譯]git revert

git revert git revert用來撤銷一個已經提交了的快照. 但不是從項目歷史中移除這個commit, 而是生成一個新的commit, 老的commit還是保留在歷史項目里面的. 這樣做的好處是防止了項目丟失歷史. 用法 git revert <commit>生成一個新的commit, 撤銷老的<commit>的所有…

圖像二值化算法總結

****************************************************************************************************************************************** 紅&#xff1a;數字圖像處理視頻教程&#xff08;兩部&#xff09; {中科院版36講視頻教程 電子科大版70講視頻教程&#xff…

html 替換反斜杠,在URL直接替換反斜杠反斜杠

我們有一個系統&#xff0c;基于Moodle的平臺&#xff0c;在這里的文件是這樣引用&#xff1a;在URL直接替換反斜杠反斜杠的http&#xff1a;// [服務器] /file.php/3/LR4/info/ index.html的現在&#xff0c;這個偉大的工程&#xff0c;但是我們的一些老師錯誤地使用落后的斜杠…

VMware橋接模式無法連網

2019獨角獸企業重金招聘Python工程師標準>>> #VMware橋接模式無法連網 在VMware上裝了個CentOS7&#xff0c;使用橋接模式連網&#xff0c;開始使用的時候沒有問題&#xff0c;可以正常上網。最近打開的時候發現上不了網了&#xff0c; 使用ifconfig查看也沒有分配到…

Java 7 中 NIO.2 的使用——第四節 文件和目錄

Files類提供了很多方法用于檢查在于你真正實際去操作一個文件或目錄。這些方法強烈推薦&#xff0c;也非常有用&#xff0c;也能避免很多異常的發生。例如&#xff0c;一個很好的習慣就是在你試著移動一個文件從一個地方到另一個地方的時候&#xff0c;先檢查文件是否存在。 檢…

計算機二級access知識點6,2019年計算機二級ACCESS考試知識點:關系數據模型

【導語】2019年計算機二級考試備考正在進行中&#xff0c;為了方便考生及時有效的備考&#xff0c;那么&#xff0c;無憂考網為您精心整理了2019年計算機二級ACCESS考試知識點&#xff1a;關系數據模型&#xff0c;歡迎大家的關注。如想獲取更多計算機二級考試的備考資料&#…