C++面向对象设计

来源:互联网 发布:虚拟化软件 比较 编辑:程序博客网 时间:2024/05/22 23:59

一. 组合(复合),继承,委托

1.composition(组合)has-a

1.1 组合举例:(Adapter 设计模式)

关系:

利用deque功能实现所有queue功能

复制代码
template <class T>class queue{protected:    deque<T> c; //deque 是两端可进出,queue是末端进,前端出 public:    bool empty() const{ return c.empty;}    size_type size() const{ return c.size();}    reference front() { return c.front(); }    reference back() { return c.back(); }    void push(const value_type& x) { c.push_back(x); }    void pop() { c.pop_front(); }}; 
复制代码

 

1.2 构造与析构

构造由内而外:

container的构造函数先调用component的默认构造函数,再执行自己

如果默认构造函数不符合要求,需自己在外部构造函数写明调用哪个内部构造函数

析构由外而内:

container的析构函数先执行自己,再调用component的析构函数

 

2. delegation(委托): composition by reference

以handle/body(Pimpl)设计模式为例

关系图: 

 存指向另一个对象的指针,composition by reference 

复制代码
// handle String.hppclass StringRep;class String {public:    String();    String(const char* s);    String(const String& s);    String &operator=(const String& s);    ~String();    . . . .private:    StringRep* rep; // pimpl};//body String.cpp#include "String.hpp"namespace {class StringRep {friend class String;    StringRep(const char* s);    ~StringRep();    int count;    char* rep;};}
复制代码

 

3 继承 (is-a)

3.1 举例:

复制代码
struct _List_node_base{    _List_node_base* _M_next;    _List_node_base* _M_prev;};template<typename _Tp>struct _List_node    : public _List_node_base{    _Tp _M_data;    };
复制代码

3.2 构造与析构

构造函数由内而外,析构函数由外而内;

derived的构造函数先调用base的默认构造函数,再执行自己

derived的析构函数先执行自己,再调用base的析构函数

base的析构函数必须为virtual,否则可能出现只调用基类析构函数,而未调用派生类析构函数的情况

 

二 虚函数与多态

1. 虚函数

函数的继承,继承的是调用权。

非虚函数:不希望子类重新定义(override 复写)它

虚函数:希望子类重新定义(override)它

纯虚函数:希望子类一定要重新定义它,你对他无定义。

复制代码
class Shape {public:    virtual void draw( ) const = 0;  //纯虚函数     virtual void error(const std::string& msg); //虚函数     int objectID( ) const;  //非虚函数     ...};class Rectangle: public Shape { ... };class Ellipse: public Shape { ... };
复制代码

 

2 以开文件为例

设计模式 Template Method (MFC即为典型的 Application framework)

共有部分在设计父类时事先实现;其他无法决定其定义的(如本例中如何读文件内容)

Serialize声明为虚函数,使其延缓到子类再重新定义,决定其具体的实现。

子类对象调用父类函数,流程如图中所示

 

上述过程模拟代码:

复制代码
#include <iostream>using namespace std;class CDocument{public:    void OnFileOpen(){        cout << "dialog..." << endl;        cout << "check file status..." << endl;        cout << "open file..." << endl;        Serialize();        cout << "close file..." << endl;        cout << "update all views..." << endl;    }    virtual void Serialize(){};}; class CMyDoc : public CDocument{public:    virtual void Serialize(){        //只有应用程序自身知道如何读取自己的文件        cout<< "CMyDoc::Serialize"<<endl;     }};int main(){    CMydoc myDoc;    myDoc.OnFileOpen();}
复制代码

 

原创粉丝点击