類的三種特殊設計【每日一題】

1.設計一個類不能被繼承 。
解法一、將該類的構造函數設爲私有函數
在C++中子類的構造函數會自動調用父類的構造函數,子類的析構函數也會自動調用父類的析構函數,要想一個類不能被繼承,我們只要把它的構造函數和析構函數都定義爲私有函數,那麼當一個類試圖從它那繼承的時候,必然會由於調用構造函數、析構函數而導致編譯錯誤。那麼既然這個類的構造和析構函數都是私有的,我們就必須通過定義公有的靜態函數來創建和釋放類的實例。

class FinalClass1 
{ 
public : 
  static FinalClass1* GetInstance() 
  { 
    return new FinalClass1; 
  } 

  static void DeleteInstance( FinalClass1* pInstance) 
  { 
    delete pInstance; 
    pInstance = 0; 
  } 

private : 
  FinalClass1() {} 
  ~FinalClass1() {} 
}; 

這個類不能被繼承,而且只能得到堆上的實例,得不到棧上的實例。
解法二、虛擬繼承

template <typename T> class MakeClass 
{
    friend T;
private:
    MakeClass(){}
    ~MakeClass(){}
};
class FinalClass2
{
public:
    FinalClass2(){}
    ~FinalClass2(){}
};

2.設計一個類只能在堆上創建對象。
分配堆區域內的對象屬於動態建立類對象過程。
編譯器對他們的內存分配是在運行時動態分配的,使用new運算符將對象建立在堆空間中。這個過程分爲兩步:
第一步,執行operator new()函數,在對中搜索合適的內存並進行分配;
第二步,調用構造函數構造對象,初始化這片內存空間。使用這種方法,間接調用類的構造函數。

那麼怎樣設計一個類能夠只在堆上創建對象呢?

很容易就想到的一個方法是把類的構造函數聲明爲私有,就無法在類的外部調用類的構造函數建立對象,只能使用new運算符來建立對象。前面已經說過,new運算符的執行過程分爲兩步,C++提供new運算符的重載其實只是允許重載operator new()函數,不能重載new運算符,而operator new()函數只用於分配內存,無法提供構造函數,所以,我們再定義一個GetObj函數,用於在堆上new對象,通過GetObj函數,建立的對象都是在堆上的new出來的,將函數聲明爲靜態的,就可以通過域作用訪問符訪問GetObj函數,在堆上建立對象。(在C++中靜態成員函數也是類函數,及這個函數不屬於某個具體的對象,而是屬於一個類的,這個類實例化的每個成員都可用,同時,這個類也可以直接調用這個函數而不用實例化一個對象。)

class BB  
{  
public:  
    static BB& GetObj(int b1 = 0,int b2 = 0)  
    {  
        return *(new BB(b1,b2));  
    }  
private:  
    BB(int b1 = 0,int b2 = 0)  
        :_b1(b1)  
        ,_b2(b2)  
    {}  
    int _b1;  
    int _b2;  
};  
void Test()  
{  

    BB b = BB::GetObj();  
}  

3.設計一個類只能在棧上創建對象。
分配在棧區域內的對象屬於靜態建立類對象過程。
編譯器對它們的內存分配是在編譯階段就完成的,是通過直接移動棧頂指針,挪出適當的空間,然後在這片內存空間上調用構造函數形成一個棧對象。使用這種方法,直接調用類的構造函數。

那麼怎樣設計一個類能夠只在棧上創建對象呢?

只有使用new運算符,對象纔會建立在堆上,所以只要禁用new運算符就可以實現類對象只能建立在棧上,將operator new()設爲私有就可以了,一定要記得,重載了new就要重載delete

class CC  
{  
public:  
    CC()  
    {}  
    ~CC()  
    {}  
private:  
    void* operator new(size_t)//重載operator new() ,這裏函數返回值和參數都是固定的  
    {}  
    void operator delete(void* ptr)//也要重載operator delete()  
    {}  
};  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章