C++面向?qū)ο蟾呒壘幊蹋ㄉ希?第三周-博覽網(wǎng)

第三周

類之間的關(guān)系

面向?qū)ο蟮乃枷耄?/p>

  • inheritance(繼承)
  • composition(復(fù)合)
  • Delegation(委托)

復(fù)合(has-a)

容器: queue:一端進一端出攀芯,deque:兩端進竞膳,兩端出

adapter:改造,適配:

對象適配器
將需要被適配的類的對象作為自己私有屬性伟桅,實現(xiàn)目標類的接口祠饺。
類適配器
繼承自需要被適配的類越驻,并且實現(xiàn)目標類的接口。

構(gòu)造函數(shù)和析構(gòu)函數(shù)

  • 構(gòu)造由內(nèi)而外

Container的構(gòu)造函數(shù)先調(diào)用Component的默認構(gòu)造函數(shù)道偷,然后再執(zhí)行自己的缀旁,默認不符合要求時,需要自己寫勺鸦。

  • 析構(gòu)函數(shù)由外而內(nèi)

Container的析構(gòu)函數(shù)首先執(zhí)行自己的并巍,然后再調(diào)用Component的析構(gòu)函數(shù)

委托(Delegation)Composition by reference

包含另一個類的指針

String中只有接口(Handle),StringRep中才是真正的實現(xiàn)(Body):(編譯防火墻)

class StringRep;
class String
{
public:
    String();
    String(const char * s);
    String &operator=(const String& s);
    ~String();
private:
    StringRep* rep;     //pimpl
}
//file String.cpp
#include "String.hpp"
class StringRep
{
    friend class String;
    StringRep(const char* s);
    ~StringRep();
    int count;      //記錄拷貝一樣的次數(shù)换途。(共享一個StringRep)懊渡,copy on write(寫時給副本去寫)
    char* rep;
}

優(yōu)點:接口對外不變刽射,內(nèi)部實現(xiàn)可以任意切換,不影響調(diào)用剃执。

繼承(is-a)

三種繼承方式:public誓禁,private,protected

虛函數(shù)和繼承結(jié)合使用

子類的對象中有父類的成分

構(gòu)造由內(nèi)而外

Derived的構(gòu)造函數(shù)先調(diào)用Base的default構(gòu)造函數(shù)肾档,然后再執(zhí)行自己的

析構(gòu)由外而內(nèi):

Derived的析構(gòu)函數(shù)首先執(zhí)行自己现横,然后在調(diào)用Base的析構(gòu)函數(shù)

Base的class的析構(gòu)函數(shù)必須是virtual,否則會出現(xiàn)undefined behavior

虛函數(shù)與多態(tài)

函數(shù)繼承的是調(diào)用權(quán)

三種:

  • non-virtual函數(shù)阁最,不希望derived class重新定義(override)的
  • virtual 希望derived class重新定義
  • pure virtual 希望derived class一定要重新定義戒祠,此函數(shù)沒有默認定義(可以有定義)
class Shape
{
    virtual void draw() const = 0;      ///pure Virtual
    virtual void error(const std::String & msg);     ///impure virtual
    int objectID() const;       ///non-virtual
}

Template Method

通過子類對象調(diào)用父類函數(shù),當父類的是虛函數(shù)速种,并且子類重定義過姜盈,執(zhí)行子類的函數(shù)定義

功能最強大:

Delegate + inheritance

委托的相關(guān)設(shè)計

單數(shù)據(jù)源,多界面顯示

//數(shù)據(jù)class:
class Subject
{
    int m_value;
    vector<Observer*> m_views;///界面類容器
public:
    void attach(Observer* obs);
    {
        m_views.push_back(obs);
    }
    void set_val(int value) ///改變值大小
    {
        m_value = value;
        notify();
    }
    void notify()       //通知界面更新
    {
        for(int i = 0;i < m_views.size();++i)
        {
            m_views[i]->update(this,m_value);
        }
    }
}

///界面類配阵,可被繼承
class Observer
{
    public:
    virtual void update(Subgect* sub馏颂,int value)= 0;
}

文件系統(tǒng):

//Composite
class Component    //父類
{
    int value;
public:
    virtual void add(Component*){}      //不能用純虛
};
class Primitive:public Component    //單體(文件)
{
                                    //繼承add棋傍,但是無實意
};
class Composite:public Component      //組合
{
    vector<Component*> vec;     ///可以包含自己或者Primitive救拉;
    void add(Component* elem)
    {c.push_back(elem);}
};

樹狀繼承體系

Prototype:

#include<iostream>
enum imageType
{
    LSAT,SPOT
};
class Image
{
    public:
    virtual void draw()=0;
    static Image * find_AndClone(imageType);
protected:
    virtual imageType returnType()=0;
    virtual Image *clone()=0;
    //As each subclass of Image is declared,it registers its prototype
    statc void addPrototype(Image *image)   ///添加子類到內(nèi)存
    {
        _prototypes[_nextSlot++] = image;
    }
private:
    //addPrototype() save each registered prototype here
    static Image *_prototype[10];
    static int _nextSlot;
};
Image *image::prototypes[];     ///定義
int Image::_nextSlot;

//client calls this public static member function when it need an instance
//of an Image subclass
Image *Image::findAndClone()       ///外部調(diào)用
{
    for(int i= 0;i < _nextSlot;i++)
        if (prototype[i]->returnType()==type)
            return _prototype[i]->clone();
}

class LandSatImage:public Image
{
public:
    imageType returnType()
    {
        return LSAT;
    }
    void draw()
    {
        cout << "LandSatImage::draw" << _id << endl;
    }
    //When clone() is called,call the one-argument ctor with a dummy arg
    Image *clone()                  ///復(fù)制本身
    {return new LandStaImage(1);}
protected:
    //This is only called from clone()
    LandSatImage(int dummy)
    {
        _id = _count++;             ///復(fù)制數(shù)量
    }
priate:
    //Mechanism for imitializing an Image subclass - this causes the
    //default ctor to be called,which registers the subclass's prototype
    static LandSatImage landSatImage;
    //This is only called when the private static data member is inited
    LandSatImage()
    {
        addPrototype(this);         ///構(gòu)造函數(shù)里添加到父類
    }
    //Norminal 'state' per instance mechanism
    int _id;
    static int _count;
};
// Register the subclass's prototype
LandSatImage LandSatImage::_landSatImage;
//Initialize the "state" per instance mechanism
int LandSatImage::_cont = 1;

class SpotImage:public Image
{
public:
    imageType returnType()
    {
        return SPOT;
    }
    void draw()
    {
        cout << "SpotImage::draw" << _id << endl;
    }
    Image *clone()
    {
        return new SpotImage(1);
    }
protected:
    SpotImage(int dummy)
    {
        _id = _count++;
    }
private:
    SpotImage()
    {
        addPrototype(this);
    }
    static SpotImage _spotImage;
    int id;
    static int _count;
};
SpotImage SpotImage::_spotImage;
int SpotImage::_count = 1;

//Simulated stream of creation requests
const int NUM_IMAGES = 8;
imageType input[NUM_IMAGES] = 
{
    LSAT,LSAT,LSAT,SPOT,LSAT,SPOT,SPOT,LSAT
};
int main()
{
    Image *image[NUM_IMAGES];
    //Given an image type,find the right prototype ,and return a clone
    for(int i= 0; i < NUM_IMAGES;i++)
        images[i] = Image::findAndClone(input[i]);
    //Demeonstrate that correct image objects have been cloned
    for(i = 0;i < NUM_IMAGES;i++)
        images[i]->draw();
    //Free the dynameic memory
    for(i = 0;i < NUM_IMAGES;i++)
        delete images[i];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市瘫拣,隨后出現(xiàn)的幾起案子亿絮,更是在濱河造成了極大的恐慌,老刑警劉巖麸拄,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件派昧,死亡現(xiàn)場離奇詭異,居然都是意外死亡拢切,警方通過查閱死者的電腦和手機蒂萎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來淮椰,“玉大人五慈,你說我怎么就攤上這事≈魉耄” “怎么了泻拦?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長黔牵。 經(jīng)常有香客問我聪轿,道長,這世上最難降的妖魔是什么猾浦? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任陆错,我火速辦了婚禮灯抛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘音瓷。我一直安慰自己对嚼,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布绳慎。 她就那樣靜靜地躺著纵竖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪杏愤。 梳的紋絲不亂的頭發(fā)上靡砌,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音珊楼,去河邊找鬼通殃。 笑死,一個胖子當著我的面吹牛厕宗,可吹牛的內(nèi)容都是我干的画舌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼已慢,長吁一口氣:“原來是場噩夢啊……” “哼曲聂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起佑惠,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤朋腋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后兢仰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乍丈,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡剂碴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年把将,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忆矛。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡察蹲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出催训,到底是詐尸還是另有隱情洽议,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布漫拭,位于F島的核電站亚兄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏采驻。R本人自食惡果不足惜审胚,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一匈勋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧膳叨,春花似錦洽洁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至龄坪,卻和暖如春昭雌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背健田。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工城豁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抄课。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓唱星,卻偏偏與公主長得像,于是被迫代替她去往敵國和親跟磨。 傳聞我的和親對象是個殘疾皇子间聊,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容