I. Combination (composite), inheritance, delegation
1.composition (combination) has-a
1.1 Combination Example: (Adapter design mode)
Relationship:
Implement all queue functions with the Deque feature
Template <classT>classqueue{protected: Deque<T> C;//deque are both ends accessible, the queue is the end-entry, the front-end is out Public: BOOLEmpty ()Const{returnC.empty;} Size_type size ()Const{returnc.size ();} Reference Front () {returnC.front ();} Reference back () {returnc.back ();} voidPushConstvalue_type&x) {c.push_back (x);} voidpop () {C.pop_front ();}};
1.2 Construction and destruction
Constructed from inside to outer:
The constructor of the container first invokes the default constructor of component and then executes its own
If the default constructor does not meet the requirements, you need to indicate in the external constructor which internal constructor to call
The destruction is from the outside and inside:
Container's destructor executes itself before calling component's destructor
2. Delegation (commissioned): Composition by reference
Take Handle/body (Pimpl) design pattern as an example
Diagram:
Save a pointer to another object, composition by reference
//Handle STRING.HPPclassStringrep;classString { Public: String (); String (Const Char*s); String (Conststring&s); String&operator=(Conststring&s); ~String (); . . . .Private: Stringrep* REP;//Pimpl};//Body String.cpp#include"string.hpp"namespace {classStringrep {friendclassString; Stringrep (Const Char*s); ~Stringrep (); intcount; Char*rep;};}
3 Inheritance (IS-A)
3.1 Examples:
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 Construction and destruction
The constructor is from the inside out, and the destructor is inside and out;
The constructor of derived first calls the default constructor of base and then executes its own
The destructor of derived executes itself before invoking the destructor of base
The destructor for base must be virtual, otherwise the behavior is undefined
Two virtual functions and polymorphic
1. Virtual functions
The inheritance of a function is the right to call.
Non-virtual functions: Do not want subclasses to be redefined (override replication) it
Virtual function: You want the subclass to redefine (override) it
Pure virtual function: you want the subclass to redefine it, you have no definition for him.
classShape { Public: Virtual voidDraw ()Const=0;//Pure virtual function Virtual voidErrorConstSTD::string& msg);//Virtual Functions intObjectID ()Const;//non-virtual functions ...};classRectangle: PublicShape {...};classEllipse: PublicShape {...};
2 to open a file for example
Design pattern Template Method (MFC is the typical application framework)
The common part is implemented in advance when designing the parent class, others cannot determine its definition (as in this example how to read the contents of the file)
Serialize is declared as a virtual function, so that it is deferred to subclasses and redefined, determining its specific implementation.
The subclass object calls the parent class function, as shown in the process
The above procedure simulates the code:
#include <iostream>using namespacestd;classcdocument{ Public: voidOnFileOpen () {cout<<"dialog ..."<<Endl; cout<<"Check file status ..."<<Endl; cout<<"Open File ..."<<Endl; Serialize (); cout<<"Close File ..."<<Endl; cout<<"Update all ..."<<Endl; } Virtual voidSerialize () {};}; classCmydoc: Publiccdocument{ Public: Virtual voidSerialize () {//only the application itself knows how to read its own filescout<<"cmydoc::serialize"<<Endl; }};intMain () {Cmydoc myDoc; Mydoc.onfileopen ();}
C + + Object-oriented Programming note 3 (Object-oriented section)