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 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 vec;     ///可以包含自己或者Primitive;
    void add(Component* elem)
    {c.push_back(elem);}
};

树状继承体系

Prototype:

#include
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];
}

你可能感兴趣的:(C++面向对象高级编程(上)-第三周-博览网)