C++面向对象高级编程(上)-第三周-博览网

第三周

类之间的关系

面向对象的思想:

  • inheritance(继承)
  • composition(复合)
  • Delegation(委托)

复合(has-a)

容器: queue:一端进一端出,deque:两端进,两端出

adapter:改造,适配:

对象适配器
将需要被适配的类的对象作为自己私有属性,实现目标类的接口。
类适配器
继承自需要被适配的类,并且实现目标类的接口。

构造函数和析构函数

  • 构造由内而外

Container的构造函数先调用Component的默认构造函数,然后再执行自己的,默认不符合要求时,需要自己写。

  • 析构函数由外而内

Container的析构函数首先执行自己的,然后再调用Component的析构函数

委托(Delegation)Composition by reference

包含另一个类的指针

String中只有接口(Handle),StringRep中才是真正的实现(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;      //记录拷贝一样的次数。(共享一个StringRep),copy on write(写时给副本去写)
    char* rep;
}

优点:接口对外不变,内部实现可以任意切换,不影响调用。

继承(is-a)

三种继承方式:public,private,protected

虚函数和继承结合使用

子类的对象中有父类的成分

构造由内而外

Derived的构造函数先调用Base的default构造函数,然后再执行自己的

析构由外而内:

Derived的析构函数首先执行自己,然后在调用Base的析构函数

Base的class的析构函数必须是virtual,否则会出现undefined behavior

虚函数与多态

函数继承的是调用权

三种:

  • non-virtual函数,不希望derived class重新定义(override)的
  • virtual 希望derived class重新定义
  • pure virtual 希望derived class一定要重新定义,此函数没有默认定义(可以有定义)
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

通过子类对象调用父类函数,当父类的是虚函数,并且子类重定义过,执行子类的函数定义

功能最强大:

Delegate + inheritance

委托的相关设计

单数据源,多界面显示

//数据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;
}

文件系统:

//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)   ///添加子类到内存
    {
        _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()       ///外部调用
{
    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()                  ///复制本身
    {return new LandStaImage(1);}
protected:
    //This is only called from clone()
    LandSatImage(int dummy)
    {
        _id = _count++;             ///复制数量
    }
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);         ///构造函数里添加到父类
    }
    //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];
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容