面向对象编程设计模式
复合设计模式
复合的情况示例如下:一般情况下低层容器的功能很强大,基于此此层容器构造的类如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| template <class T, class Sequence = deque<T>> class queue { ... protected: Sequence c; 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(); }; }
|
从内存角度:其大小=各个低层容器+自己的数据大小;
复合关系下的构造与析构
构造函数:container的构造函数首先调用内部component的默认构造函数,然后再执行自己的构造函数;
析构函数:container首先调用自己的析构函数,然后再调用内部各component的默认析构函数。
委托
1 2 3 4 5 6 7 8 9 10 11 12
| class StringRep; class String { public: String(); String(const char* s); String(const String& s); String &operator = (const String& s); ~String(); ... private: StringRep* rep; }
|
此StringRep对象实现如下所示:
1 2 3 4 5 6 7 8 9 10
| #include "String.hpp" namespace { class StringRep { friend class String; StringRep(const char* s); ~StringRep(); int count; char* rep; }; }
|
container可以在任意时间将数据委托给这个对象(上面的示例中是StringRep),让这个对象处理数据。container和里面的对象寿命是不一致的。
继承
继承语法如下:
1 2 3 4 5 6 7 8 9 10 11 12
| 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; };
|
父类的数据完全派生类被继承下来,其构造函数与析构函数应该与复合中一致的。
继承与虚函数
非虚函数:不希望派生类重新定义;
虚函数:在成员函数前加上virtual
关键字,希望派生类重新定义,但其有默认的定义;
纯虚函数:交给派生类重新定义的,没有默认定义;
1 2 3 4 5 6
| class Shape { public: virtual void draw() const=0; virtual void error (const std::string& msg); int objectID() const; }
|
委托+继承