美文网首页
GeekBand C++面向对象高级编程(上) Thrid We

GeekBand C++面向对象高级编程(上) Thrid We

作者: 不会飞的鸟人 | 来源:发表于2016-05-29 23:28 被阅读0次

    GeekBand C++面向对象高级编程(上) Thrid Week

    面向对象编程(Object Oriented Progamming)

    Inheritance (继承)

    继承表示一种 ‘is-a' 的关系。有基类(base class) 和 派生类(derived class)。 继承分为单个继承和多重继承,同时继承的访问权限也有public,private,protected(默认是private)。

    class Shape
    {
    public:
        Shape() {}
        virtual ~Shape() {}
    private:
        int no_;
    };
    
    class Rectangle: public Shape
    {
    public:
        Rectangle() {}
        virtual ~Rectangle() {}
    private:
        int x_;
        int y_;
    };
    

    Rectangle 继承自 Shape,Rectangle可以访问基类的成员函数。
    继承关系的构造函数是由内而外,子类的构造函数先调用基类的默认构造函数,然后才执行自己。

    Rectangle::Rectangle(...): Shape() {...} // Shape() 是编译器附加的代码
    

    析构函数是由外而内,子类的析构函数首先执行自己,然后才调用基类的析构函数。

    Rectangle::~Rectangle(...) { ... ~Shape() } // ~Shape() 是编译器附加的代码
    

    base class 的 析构函数必须写成virtual,否则在以下情况会出现部分析构的情况(表现为 undifined behavior)。

    Shape* ps = new Rectangle();
    delete ps; // 这种情况下如果基类的析构函数不是virtual,只能执行基类的析构函数,而子类的部分不能析构。

    继承中的虚函数:

    1. non-virtual 函数: 不希望子类重写(override)
    2. virtual 函数: 希望派生类重写它,如果派生类没有重写,可以使用基类的默认定义版本
    3. pure-virtual 函数: 派生类一定要重新定义。 定义了纯虚函数则该类被认为为抽象类。

    Composition (复合)

    复合是一种表示 'has-a' 的关系。一个类中包含了另一个类的实例。

    class StringRep;
    class String {
    public:
        String();
        String(const String&s)
        String &operator=(const Stirng&s);
        ~String();
    private:
        StringRep rep;
    };
    

    复合方式的构造函数由内而外,Container的构造函数首先调用Component的defaul构造函数,然后才执行自己。

    Container::Container(...):Component() {...};
    

    析构的时候是由外而内,Container的析构函数首先执行自己,然后才调用Component的析构函数。

    Container::~Container(...) {... ~Component() };
    

    Delegation (委托)

    委托 是一种以指针方式的复合。一个类中包含了另一个类的指针。

    class StringRep;
    class String {
    public:
        String();
        String(const String&s)
        String &operator=(const Stirng&s);
        ~String();
    private:
        StringRep* rep;
    };
    

    面向对象的设计模式 (Object Oriented Design)

    Template Method

    模版方法 是预先定义好操作的骨架,预留一些步骤的实现给子类。
    C++ 中继承中的虚函数即可完成这样的功能。

    CDocument::OnFileOpen()
    {
    ...
    Serialize();
    ...
    }
    
    class CMyDoc:public CDocumment
    {
    virtual Serialize() {...}
    }
    

    Observer

    观察者模式,是定义一种一对多的依赖关系,当这这其中的一个改变时,所有其它依赖的对象都能自动的被通知和更新。

    在C++ 中可以使用 Delegation+Inheritance 实现。

    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(Subject* sub, int value) = 0;
    };
    
    class Observer1: public Observer
    {
        void update(int v)
        {
        ...
        }
    };
    class Observer2: public Observer
    {
        void update(int v)
        {
        ...
        }
    };
    

    Composite

    Composite的典型例子就是文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式Composite。
    C++ 中可以通过 Delegation+Inheritance 实现

    class Componet
    {
        int value;
    public:
        Componet(int val) {value = val;}
        virtual void add(Component*) {}
    };
    
    class Composite:public Component
    {
        vector<Component*> c;
    public:
        Composite(int val):Component(val) {}
        
        void add(Component* elem) {
            c.push_back(elem);
        }
    };
    
    class Leaf:public Component
    {
    public:
        Leaf(int val):Component(val) {}
    };
    

    相关文章

      网友评论

          本文标题:GeekBand C++面向对象高级编程(上) Thrid We

          本文链接:https://www.haomeiwen.com/subject/savqdttx.html