zz: C++中構造函數或析構函數定義爲private

C++中構造函數或析構函數定義爲private

轉自:http://www.blogjava.net/fhtdy2004/archive/2009/05/30/278971.htmlhtml

  不少狀況下要求當前的程序中只有一個object。例如一個程序只有一個和數據庫的鏈接,只有一個鼠標的object。一般咱們都將構造函數的聲明置於public區段,假如咱們將其放入private區段中會發生什麼樣的後果?這意味着什麼?java

(1)構造函數定義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() {}
};c++

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

      這個例子使用了私有構造函數,GetInstance()做爲OnlyHeapClass的靜態成員函數來在內存中建立對象:因爲要跨函數傳遞而且不能使用值傳遞方式,因此咱們選擇在堆上建立對象,這樣即便getInstance()退出,對象也不會隨之釋放,能夠手動釋放。
    
      構造函數私有化的類的設計保證了其餘類不能從這個類派生或者建立類的實例,還有這樣的用途:例如,實現這樣一個class:它在內存中至多存在一個,或者指定數量個的對象(能夠在class的私有域中添加一個static類型的計數器,它的初值置爲0,而後在GetInstance()中做些限制:每次調用它時先檢查計數器的值是否已經達到對象個數的上限值,若是是則產生錯誤,不然才new出新的對象,同時將計數器的值增1.最後,爲了不值複製時產生新的對象副本,除了將構造函數置爲私有外,複製構造函數也要特別聲明並置爲私有。
      若是將構造函數設計成Protected,也能夠實現一樣的目的,可是能夠被繼承。數據庫

(2)析構函數private     數組

   另外如何保證只能在堆上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   的實現上。樓主可查找   singleton   的資料來了解它是怎麼一回事。this

分類: c/c++spa

相關文章
相關標籤/搜索