關於繼承與委託設計筆記----C++學習之路

  1.Composite


假如寫一個file system,可以知道一個文件系統可以包括有目錄和文件。

目錄裏面可以放文件。

由圖中可得,左邊的Primitive就是一個文件,右邊的Composite就是一個目錄。

目錄中需要一個容器來來存放文件,當然,目錄中也可以存放目錄,這個時候vector中存放的指針應該怎麼做?

那就讓文件和目錄同時繼承Component,讓vector來存放Component的指針。

並且目錄又可以委託Component*。

這樣Composite就可以存放文件也可以存放目錄。

大致的代碼:

class Component
{
    int value;
public:
    Component(int val){ value=val; }
    virtual void add (Component*) {}
};
class Primitive : public Component
{
public:
    Primitive(int val):Component(val){}
};
class Composite : public Component
{
    vector<Component*> c;
public:
    Composite(int val) : Component(val) {}
    void add(Component* elem)
    {
        c.pubsh_back(elem);
    }
};
爲什麼Component中的add不寫成純虛函數,因爲Primitive一個文件可不能再來add什麼,所以設置成一個空虛函數。

爲什麼vector中存放的是指針?因爲容器中存放的東西一定要大小一樣的,所以存放指針。

整個看起來就是23個設計模式中的一種Composite設計模式。


  2.Prototype



註釋:(圖中帶有下劃線的是靜態類型,帶-號的爲private,帶#爲protected,帶+號,一般默認不加爲public)

Prototype原型設計模式,主要用於來寫未來的類,這樣的類我還不知道叫什麼,一般用於框架的構建。

用於,當未來我要寫一個LandSatImage的類,我讓它拷貝一份原型,讓最頂上的Image知道。

通俗來說,就是每一個子類都有一個自己,每一個子類都通過自己的構造函數把自己這個個體放進Image中。

並且每個子類都有一個clone,讓框架端知道自己的原型,並且通過原型來調用clone來製造子類的副本。

父類代碼:

#include <iosteam.h>

enum imageType
{
  LSAT,SPOT
};

class Image
{
public :
    virtual void draw() = 0; 
    static Image *findAndClone(imageType);
protected:
    virtual imgeType returnType() = 0;
    virtual Image *clone() = 0;
    static void addPrototype(Image *image)
    {
        _prototypes[_nextSlot++] = image;
    }
private:
    static Image *_prototyles[10];
    static int _nextSlot;
};
Image *Image::_prototype[];
int Image::_nextSlot;
靜態的聲明要在類外定義給內存。
Image *Image::findAndClone(imageType type)
{
    for(int i = 0; i<_nextSlot; i++)
        if(_prototypes[i]->returnType() == type)
            return  _prototypes[i]->clone();
}
這裏利用枚舉,作爲示例,實際情況可能會使用類的名字。

找到原型之後調用clone做一個副本。


子類代碼:

class LandSatImage : public Image
{
public :
    imageType returnType(){return LSAT;}
    void draw(){cout<<"LandSatImage::draw"<<id<<endl;
    Image *clone(){return new LandSatImage(1); }
protected:
    LandSatImage(int dummy){_id=_count++; }
private:
    static LandSatImage _landeSatImage;
    LandSatImage(){ addProtetype(this); }
    int _id;
    static int _count;
};
LandSatImage LandSatImage::_landSatImage;
int LandSatImage::_count = 1;
最後看看子類圖中有-LanSatImage();#LandSatImage(int);爲什麼會有兩個構造函數分別再private與protecte。

我們先把靜態的自己放到框架端上了,並且實現findAndClone中的clone(),這個時候又要調用構造函數,

這次調用的構造函數不能調用-LandSatImage(),因爲如果再調用的話,又會往上加入一個原型。所以必須

要再寫一個構造函數,爲什麼不能寫在public中?因爲這個設計模式不是讓外界來讓他創建,而是讓原型來創建。

爲了區分開兩個構造函數,那就加一個參數int,但是這個int 根本用不到。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章