<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-204  評論-149  文章-0  trackbacks-0

     很多情況下要求當(dāng)前的程序中只有一個object。例如一個程序只有一個和數(shù)據(jù)庫的連接,只有一個鼠標(biāo)的object。通常我們都將構(gòu)造函數(shù)的聲明置于public區(qū)段,假如我們將
    其放入private區(qū)段中會發(fā)生什么樣的后果?這意味著什么?
          當(dāng)我們在程序中聲明一個對象時,編譯器為調(diào)用構(gòu)造函數(shù)(如果有的話),而這個調(diào)用將通常是外部的,也就是說它不屬于class對象本身的調(diào)用,假如構(gòu)造函數(shù)是私有的,
    由于在class外部不允許訪問私有成員,所以這將導(dǎo)致編譯出錯。
          然而,對于class本身,可以利用它的static公有成員,因為它們獨立于class對象之外,不必產(chǎn)生對象也可以使用它們。
          此時因為構(gòu)造函數(shù)被class私有化,所以我們要創(chuàng)建出對象,就必須能夠訪問到class的私有域;這一點只有class的成員可以做得到;但在我們建構(gòu)出其對象之前,怎么能利用它
    的成員呢?static公有成員,它是獨立于class對象而存在的,“我們”可以訪問得到。假如在某個static函數(shù)中創(chuàng)建了該class的對象,并以引用或者指針的形式將其返回(這里不
    以對象返回,主要是構(gòu)造函數(shù)是私有的,外部不能創(chuàng)建臨時對象),就獲得了這個對象的使用權(quán)。
          下面是例子:
    class OnlyHeapClass
    {
    public:
       static OnlyHeapClass* GetInstance()
           {
                  // 創(chuàng)建一個OnlyHeapClass對象并返回其指針
                  return (new OnlyHeapClass);
           }
       void Destroy();
    private:
           OnlyHeapClass() { }
           ~OnlyHeapClass() {}
    };

    int main()
    {
           OnlyHeapClass *p = OnlyHeapClass::GetInstance();
           ... // 使用*p
           delete p;
           return 0;
    }

          這個例子使用了私有構(gòu)造函數(shù),GetInstance()作為OnlyHeapClass的靜態(tài)成員函數(shù)來在內(nèi)存中創(chuàng)建對象:由于要跨函數(shù)傳遞并且不能使用值傳遞方式,所以我們選擇在堆上
    創(chuàng)建對象,這樣即使getInstance()退出,對象也不會隨之釋放,可以手動釋放。
       
          構(gòu)造函數(shù)私有化的類的設(shè)計保證了其他類不能從這個類派生或者創(chuàng)建類的實例,還有這樣的用途:例如,實現(xiàn)這樣一個class:它在內(nèi)存中至多存在一個,或者指定數(shù)量個
    的對象(可以在class的私有域中添加一個static類型的計數(shù)器,它的初值置為0,然后在GetInstance()中作些限制:每次調(diào)用它時先檢查計數(shù)器的值是否已經(jīng)達(dá)到對象個數(shù)的
    上限值,如果是則產(chǎn)生錯誤,否則才new出新的對象,同時將計數(shù)器的值增1.最后,為了避免值復(fù)制時產(chǎn)生新的對象副本,除了將構(gòu)造函數(shù)置為私有外,復(fù)制構(gòu)造函數(shù)也要特別
    聲明并置為私有。
          如果將構(gòu)造函數(shù)設(shè)計成Protected,也可以實現(xiàn)同樣的目的,但是可以被繼承。

           另外如何保證只能在堆上new一個新的類對象呢?只需把析構(gòu)函數(shù)定義為私有成員。
          原因是C++是一個靜態(tài)綁定的語言。在編譯過程中,所有的非虛函數(shù)調(diào)用都必須分析完成。即使是虛函數(shù),也需檢查可訪問性。因些,當(dāng)在棧上生成對象時,對象會自動析構(gòu),
    也就說析構(gòu)函數(shù)必須可以訪問。而堆上生成對象,由于析構(gòu)時機由程序員控制,所以不一定需要析構(gòu)函數(shù)。保證了不能在棧上生成對象后,需要證明能在堆上生成它。這里OnlyHeapClass與一般對象唯一的區(qū)別在于它的析構(gòu)函數(shù)為私有。delete操作會調(diào)用析構(gòu)函數(shù)。所以不能編譯。
           那么如何釋放它呢?答案也很簡單,提供一個成員函數(shù),完成delete操作。在成員函數(shù)中,析構(gòu)函數(shù)是可以訪問的。當(dāng)然detele操作也是可以編譯通過。
    void OnlyHeapClass::Destroy() {
            delete this;
    }
        構(gòu)造函數(shù)私有化的類的設(shè)計可以保證只能用new命令在堆中來生成對象,只能動態(tài)的去創(chuàng)建對象,這樣可以自由的控制對象的生命周期。但是,這樣的類需要提供創(chuàng)建和撤銷
    的公共接口。
        另外重載delete,new為私有可以達(dá)到要求對象創(chuàng)建于棧上的目的,用placement new也可以創(chuàng)建在棧上。



    ---------------------------------------------------------------------------------------------------------------------------------
    還是不懂啊:  
      1.為什么要自己調(diào)用呢?對象結(jié)束生存期時不就自動調(diào)用析構(gòu)函數(shù)了嗎?什么情況下需要自己調(diào)用析構(gòu)函數(shù)呢?  
      ================================================================  
      比如這樣一種情況,你希望在析構(gòu)之前必須做一些事情,但是用你類的人并不知道,  
      那么你就可以重新寫一個函數(shù),里面把要做的事情全部做完了再調(diào)用析構(gòu)函數(shù)。  
      這樣人家只能調(diào)用你這個函數(shù)析構(gòu)對象,從而保證了析構(gòu)前一定會做你要求的動作。  
       
      2.什么情況下才用得著只生成堆對象呢?  
      ================================  
      堆對象就是new出來的,相對于棧對象而言。什么情況下要new,什么情況下在棧里面  
      提前分配,無非就是何時該用動態(tài),何時該用靜態(tài)生成的問題。這個要根據(jù)具體情況  
      具體分析。比如你在一個函數(shù)里面事先知道某個對象最多只可能10個,那么你就可以  
      定義這個對象的一個數(shù)組。10個元素,每個元素都是一個棧對象。如果你無法確定數(shù)  
      字,那么你就可以定義一個這個對象的指針,需要創(chuàng)建的時候就new出來,并且用list  
      或者vector管理起來。  

    ---------------------------------------------------------------------------------------------------------------------------------
    類中“私有”權(quán)限的含義就是:私有成員只能在類域內(nèi)被訪問,不能在類域外進行訪問。  
       
      把析構(gòu)函數(shù)定義為私有的,就阻止了用戶在類域外對析構(gòu)函數(shù)的使用。這表現(xiàn)在如下兩個方面:  
       
      1.   禁止用戶對此類型的變量進行定義,即禁止在棧內(nèi)存空間內(nèi)創(chuàng)建此類型的對象。要創(chuàng)建對象,只能用   new   在堆上進行。  
       
      2.   禁止用戶在程序中使用   delete   刪除此類型對象。對象的刪除只能在類內(nèi)實現(xiàn),也就是說只有類的實現(xiàn)者才有可能實現(xiàn)對對象的   delete,用戶不能隨便刪除對象。如果用戶想刪除對象的話,只能按照類的實現(xiàn)者提供的方法進行。  
       
      可見,這樣做之后大大限制了用戶對此類的使用。一般來說不要這樣做;通常這樣做是用來達(dá)到特殊的目的,比如在   singleton   的實現(xiàn)上。樓主可查找   singleton   的資料來了解它是怎么一回事。
    posted on 2009-05-30 00:22 Frank_Fang 閱讀(5399) 評論(3)  編輯  收藏 所屬分類: C++編程

    評論:
    # re: C++中將構(gòu)造函數(shù)或析構(gòu)函數(shù)定義為private 2014-07-25 15:02 | yangxin
    講的非常好 解決了我的困惑 非常感謝 贊一個  回復(fù)  更多評論
      
    # re: C++中將構(gòu)造函數(shù)或析構(gòu)函數(shù)定義為private[未登錄] 2015-09-14 09:00 | h
    # re: C++中將構(gòu)造函數(shù)或析構(gòu)函數(shù)定義為private[未登錄] 2015-09-14 09:02 | h
    理論上來說,static成員函數(shù)是不能訪問非static成員函數(shù),為什么這里可以調(diào)用呢?

    求解~


      回復(fù)  更多評論
      
    主站蜘蛛池模板: 在线观看亚洲AV每日更新无码| 亚洲va中文字幕无码久久| 亚洲国产成人精品激情| 美丽姑娘免费观看在线观看中文版| 久久精品国产亚洲网站| 免费无码又爽又刺激网站| 国产亚洲真人做受在线观看| a级毛片无码免费真人久久| 国产AV无码专区亚洲AVJULIA| 免费h视频在线观看| 2022年亚洲午夜一区二区福利| 114级毛片免费观看| 亚洲av无码不卡久久| 日本一区免费电影| 免费无码又爽又黄又刺激网站 | 一个人看的免费视频www在线高清动漫 | 日韩精品视频免费观看| 美女扒开尿口给男人爽免费视频| 免费人成视频x8x8入口| 国产精品成人啪精品视频免费| 亚洲精品无码高潮喷水在线| 精品一区二区三区无码免费视频 | 色噜噜的亚洲男人的天堂| 亚洲AV无码乱码在线观看| 精品97国产免费人成视频 | 亚洲w码欧洲s码免费| 免费的涩涩视频在线播放| 免费一级毛片在线播放放视频| 亚洲精品白浆高清久久久久久| 又大又硬又爽又粗又快的视频免费| 亚洲中文字幕精品久久| 亚洲精品无码久久久| 日韩精品无码免费一区二区三区| 亚洲情A成黄在线观看动漫软件| 国产嫩草影院精品免费网址| a在线观看免费视频| 亚洲第一男人天堂| 亚洲人成网77777色在线播放| 国产精品亚洲玖玖玖在线观看| 国产精品偷伦视频观看免费| 亚洲日本va一区二区三区|