亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

詳解C++中如何將構造函數或析構函數的訪問權限定為private

2020-05-23 14:07:14
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了詳解C++中如何將構造函數或析構函數的訪問權限定為private的方法,文中還解釋了構造函數與虛函數的區別,需要的朋友可以參考下
 

今天面試被問到了這個單例模式常用到的技術手段,下面進行分析:
        很多情況下要求當前的程序中只有一個object。例如一個程序只有一個和數據庫的連接,只有一個鼠標的object。通常我們都將構造函數的聲明置于public區段,假如我們將其放入private區段中會發生什么樣的后果?這意味著什么?
        當我們在程序中聲明一個對象時,編譯器為調用構造函數(如果有的話),而這個調用將通常是外部的,也就是說它不屬于class對象本身的調用,假如構造函數是私有的,由于在class外部不允許訪問私有成員,所以這將導致編譯出錯。
        然而,對于class本身,可以利用它的static公有成員,因為它們獨立于class對象之外,不必產生對象也可以使用它們。
        此時因為構造函數被class私有化,所以我們要創建出對象,就必須能夠訪問到class的私有域;這一點只有class的成員可以做得到;但在我們建構出其對象之前,怎么能利用它的成員呢?static公有成員,它是獨立于class對象而存在的,“我們”可以訪問得到。假如在某個static函數中創建了該class的對象,并以引用或者指針的形式將其返回(這里不以對象返回,主要是構造函數是私有的,外部不能創建臨時對象),就獲得了這個對象的使用權。
下面是例子:

class OnlyHeapClass { public:   static OnlyHeapClass* GetInstance()   {     // 創建一個OnlyHeapClass對象并返回其指針     return (new OnlyHeapClass);   }   void Destroy(); private:   OnlyHeapClass() { }   ~OnlyHeapClass() {} };  int main() {   OnlyHeapClass *p = OnlyHeapClass::GetInstance();   ... // 使用*p   delete p;   return 0; } 

 
        這個例子使用了私有構造函數,GetInstance()作為OnlyHeapClass的靜態成員函數來在內存中創建對象:由于要跨函數傳遞并且不能使用值傳遞方式,所以我們選擇在堆上創建對象,這樣即使getInstance()退出,對象也不會隨之釋放,可以手動釋放。
        構造函數私有化的類的設計保證了其他類不能從這個類派生或者創建類的實例,還有這樣的用途:例如,實現這樣一個class:它在內存中至多存在一個,或者指定數量個的對象(可以在class的私有域中添加一個static類型的計數器,它的初值置為0,然后在GetInstance()中作些限制:每次調用它時先檢查計數器的值是否已經達到對象個數的上限值,如果是則產生錯誤,否則才new出新的對象,同時將計數器的值增1.最后,為了避免值復制時產生新的對象副本,除了將構造函數置為私有外,復制構造函數也要特別聲明并置為私有。
        如果將構造函數設計成Protected,也可以實現同樣的目的,但是可以被繼承。
        另外如何保證只能在堆上new一個新的類對象呢?只需把析構函數定義為私有成員。
        原因是C++是一個靜態綁定的語言。在編譯過程中,所有的非虛函數調用都必須分析完成。即使是虛函數,也需檢查可訪問性。因些,當在棧上生成對象時,對象會自動析構,也就說析構函數必須可以訪問。而堆上生成對象,由于析構時機由程序員控制,所以不一定需要析構函數。保證了不能在棧上生成對象后,需要證明能在堆上生成它。這里OnlyHeapClass與一般對象唯一的區別在于它的析構函數為私有。delete操作會調用析構函數。所以不能編譯。
        那么如何釋放它呢?答案也很簡單,提供一個成員函數,完成delete操作。在成員函數中,析構函數是可以訪問的。當然detele操作也是可以編譯通過。

void OnlyHeapClass::Destroy() {   delete this; } 

        構造函數私有化的類的設計可以保證只能用new命令在堆中來生成對象,只能動態的去創建對象,這樣可以自由的控制對象的生命周期。但是,這樣的類需要提供創建和撤銷的公共接口。
        另外重載delete,new為私有可以達到要求對象創建于棧上的目的,用placement new也可以創建在棧上。

補充:
1.為什么要自己調用呢?對象結束生存期時不就自動調用析構函數了嗎?什么情況下需要自己調用析構函數呢?   
        比如這樣一種情況,你希望在析構之前必須做一些事情,但是用你類的人并不知道, 那么你就可以重新寫一個函數,里面把要做的事情全部做完了再調用析構函數。 這樣人家只能調用你這個函數析構對象,從而保證了析構前一定會做你要求的動作。

2.什么情況下才用得著只生成堆對象呢? 
        堆對象就是new出來的,相對于棧對象而言。什么情況下要new,什么情況下在棧里面 提前分配,無非就是何時該用動態,何時該用靜態生成的問題。這個要根據具體情況具體分析。比如你在一個函數里面事先知道某個對象最多只可能10個,那么你就可以 定義這個對象的一個數組。10個元素,每個元素都是一個棧對象。如果你無法確定數 字,那么你就可以定義一個這個對象的指針,需要創建的時候就new出來,并且用list 或者vector管理起來。

        類中“私有”權限的含義就是:私有成員只能在類域內被訪問,不能在類域外進行訪問。

        把析構函數定義為私有的,就阻止了用戶在類域外對析構函數的使用。這表現在如下兩個方面:

        1. 禁止用戶對此類型的變量進行定義,即禁止在棧內存空間內創建此類型的對象。要創建對象,只能用 new 在堆上進行。

        2. 禁止用戶在程序中使用 delete 刪除此類型對象。對象的刪除只能在類內實現,也就是說只有類的實現者才有可能實現對對象的 delete,用戶不能隨便刪除對象。如果用戶想刪除對象的話,只能按照類的實現者提供的方法進行。

        可見,這樣做之后大大限制了用戶對此類的使用。一般來說不要這樣做;通常這樣做是用來達到特殊的目的,比如在 singleton 的實現上。

PS:構造函數為什么不能是虛函數
另外再來說一下構造函數和虛函數的區別:
       1. 從存儲空間角度,虛函數對應一個指向vtable虛函數表的指針,這大家都知道,可是這個指向vtable的指針其實是存儲在對象的內存空間的。問題出來了,如果構造函數是虛的,就需要通過 vtable來調用,可是對象還沒有實例化,也就是內存空間還沒有,怎么找vtable呢?所以構造函數不能是虛函數。
        2. 從使用角度,虛函數主要用于在信息不全的情況下,能使重載的函數得到對應的調用。構造函數本身就是要初始化實例,那使用虛函數也沒有實際意義呀。所以構造函數沒有必要是虛函數。虛函數的作用在于通過父類的指針或者引用來調用它的時候能夠變成調用子類的那個成員函數。而構造函數是在創建對象時自動調用的,不可能通過父類的指針或者引用去調用,因此也就規定構造函數不能是虛函數。
        3. 構造函數不需要是虛函數,也不允許是虛函數,因為創建一個對象時我們總是要明確指定對象的類型,盡管我們可能通過實驗室的基類的指針或引用去訪問它但析構卻不一定,我們往往通過基類的指針來銷毀對象。這時候如果析構函數不是虛函數,就不能正確識別對象類型從而不能正確調用析構函數。
        4. 從實現上看,vbtl在構造函數調用后才建立,因而構造函數不可能成為虛函數從實際含義上看,在調用構造函數時還不能確定對象的真實類型(因為子類會調父類的構造函數);而且構造函數的作用是提供初始化,在對象生命期只執行一次,不是對象的動態行為,也沒有必要成為虛函數。
        5. 當一個構造函數被調用時,它做的首要的事情之一是初始化它的VPTR。因此,它只能知道它是“當前”類的,而完全忽視這個對象后面是否還有繼承者。當編譯器為這個構造函數產生代碼時,它是為這個類的構造函數產生代碼——既不是為基類,也不是為它的派生類(因為類不知道誰繼承它)。所以它使用的VPTR必須是對于這個類的VTABLE。而且,只要它是最后的構造函數調用,那么在這個對象的生命期內,VPTR將保持被初始化為指向這個VTABLE, 但如果接著還有一個更晚派生的構造函數被調用,這個構造函數又將設置VPTR指向它的 VTABLE,等.直到最后的構造函數結束。VPTR的狀態是由被最后調用的構造函數確定的。這就是為什么構造函數調用是從基類到更加派生類順序的另一個理由。但是,當這一系列構造函數調用正發生時,每個構造函數都已經設置VPTR指向它自己的VTABLE。如果函數調用使用虛機制,它將只產生通過它自己的VTABLE的調用,而不是最后的VTABLE(所有構造函數被調用后才會有最后的VTABLE)。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
98午夜经典影视| 91精品在线影院| 欧美成人黄色小视频| 日韩中文字幕在线看| 美女性感视频久久久| 亚洲视频自拍偷拍| 欧美午夜视频一区二区| 亚洲国产精品中文| 精品久久久久久中文字幕| 日韩精品在线播放| 国产日韩中文在线| 精品成人久久av| 国产精品男人的天堂| 亚洲自拍在线观看| 亚洲国产精品99| 日韩视频欧美视频| 国产亚洲欧美一区| 亚洲黄页视频免费观看| 热久久这里只有精品| 亚洲精品自拍偷拍| 日韩av电影中文字幕| 精品亚洲一区二区三区| 久久好看免费视频| 亚洲天堂男人天堂| 欧美精品日韩三级| 国产精品久久97| 日本最新高清不卡中文字幕| 中文字幕在线看视频国产欧美| 国产精品91在线| 久久久久久高潮国产精品视| 亚洲图片在区色| 久久久久久久国产精品视频| 国产精品视频最多的网站| 国产精品嫩草影院久久久| 久久精品国产成人精品| 亚洲精品国产精品国自产观看浪潮| 精品国产乱码久久久久酒店| 亚洲国产成人精品女人久久久| 奇米四色中文综合久久| 国产一区二区三区精品久久久| 久久久久久亚洲精品| 97久久精品人人澡人人爽缅北| 久久天天躁日日躁| 亚洲精品网站在线播放gif| 日韩视频第一页| 欧美日产国产成人免费图片| 亚洲精品国产精品国自产在线| 日韩中文字幕在线视频播放| 最近2019年手机中文字幕| 亚洲精品久久久久久下一站| 亚洲综合在线做性| 92看片淫黄大片欧美看国产片| 国产精品视频最多的网站| 亚洲国产天堂久久国产91| 国产精品久久久| 欧美性高潮床叫视频| 国产综合福利在线| 午夜精品理论片| 在线视频亚洲欧美| 日韩高清电影好看的电视剧电影| 国产精品美女无圣光视频| 日本中文字幕久久看| 欧美精品九九久久| 亚洲美女视频网| 国产激情久久久| 国产精品黄页免费高清在线观看| 国产精品久久久久9999| www.欧美三级电影.com| 亚洲第一国产精品| 欧美一级免费视频| 亚洲成色777777在线观看影院| 91久久精品久久国产性色也91| 黄网站色欧美视频| 亚洲国产日韩欧美在线99| 久久久噜久噜久久综合| 日韩精品在线视频观看| 日韩精品免费一线在线观看| 欧美激情按摩在线| 日韩精品免费在线| 国产一区二区在线播放| 欧美日韩国产激情| 欧美理论电影网| 亚洲欧美色婷婷| 国产成人精品免费视频| 日本韩国在线不卡| 亚洲影视九九影院在线观看| 国产精品免费网站| 日韩成人av网址| 欧美一级大片视频| 欧美日在线观看| 青青草国产精品一区二区| 欧美最顶级丰满的aⅴ艳星| 91天堂在线视频| 91av在线影院| 成人精品久久久| 久久精品久久久久久国产 免费| 一区二区三区高清国产| 久久在线免费视频| 欧美性感美女h网站在线观看免费| 欧美中文字幕视频在线观看| 亚洲最大成人在线| 精品成人在线视频| 国产日韩在线精品av| 精品视频中文字幕| 热re91久久精品国99热蜜臀| 色悠悠国产精品| 欧美精品一区在线播放| 中文字幕免费精品一区| 26uuu日韩精品一区二区| 久久国产精品久久久久久久久久| 欧美多人乱p欧美4p久久| 奇米成人av国产一区二区三区| 91久久精品日日躁夜夜躁国产| 亚洲国产精品成人精品| 欧美多人爱爱视频网站| 国产精品久久国产精品99gif| 中文字幕亚洲一区二区三区五十路| 91青草视频久久| 欧美国产日韩精品| 欧美日韩国产在线看| 国产自摸综合网| 神马国产精品影院av| 国产精品久久久久久久久久免费| 国产精品久久久久久一区二区| www国产91| 亚洲黄在线观看| 欧美激情图片区| 中文字幕精品—区二区| 国内精久久久久久久久久人| 日韩性生活视频| 成人免费观看49www在线观看| 欧美精品在线免费观看| 中文字幕久精品免费视频| 91丨九色丨国产在线| 尤物九九久久国产精品的分类| 456亚洲影院| 国产亚洲视频在线| 97色在线观看免费视频| 国产精品wwww| 97免费视频在线| 国产在线观看不卡| 国产香蕉精品视频一区二区三区| 国产亚洲精品久久久久久牛牛| 成人h视频在线| 日本亚洲欧洲色| 91精品国产高清自在线| 日韩中文字幕网站| 在线观看国产精品日韩av| 精品久久在线播放| 欧美风情在线观看| 亚洲国产成人爱av在线播放| 亚洲国内精品视频| 国产97色在线|日韩| 另类美女黄大片| 欧美成人午夜免费视在线看片| 亚洲精品www久久久久久广东| 国产亚洲成av人片在线观看桃| 久久久极品av| 日韩精品在线观看网站| 不卡在线观看电视剧完整版| 在线视频欧美性高潮| 国产日韩在线看| 日韩中文字幕av| 国产亚洲欧洲高清|