Before getting started with c ++ template programming, I really didn't think that c ++ could be used like this. The biggest feeling is that it is too flexible and powerful. The initial launch of the template was still in Delta3d. I felt that the template was flexible and convenient to use. In particular, a large number of templates were used in dtAI, greatly enhancing the scalability of the database.
This article is based on the new thinking of c ++ design.
First look at a piece of code:
# Include
# Include
# Include
Using namespace std; // users /////// Widget type class SliderWidget {public: SliderWidget () {std: cout <"Slider Widget created" <
Class OpNewCreateor {public: static T * create () {return new T;} protected :~ OpNewCreateor () {}}; template
Class MallocCreator {public: static T * create () {void * buf = std: malloc (sizeof (T); if (! Buf) return 0; return new (buf) T;} protected :~ MallocCreator () {}}; template
Class PrototypeCreator {public: PrototypeCreator (T * pObj = 0): pPrototype (pObj) {} T * create () {return pPrototype? PPrototype-> clone (): 0;} T * getPrototype () {return pPrototype;} void setPrototype (T * pObj) {pPrototype = pObj;} protected :~ PrototypeCreator () {} private: T * pPrototype;}; // -------------------------------------------------------------------------------- // store the template of the widget container type
Class ContainerVec {public: void push (T * widget) {mVecContainer. push_back (widget);} protected :~ ContainerVec () {} private: std: vector
MVecContainer; // Vector container}; template
Class ContainerList {public: void push (T * widget) {mListContainer. insert (widget);} protected :~ ContainerList () {} private: std: list
MListContainer; // List container}; // -------------------------------------------------------------------------------- // -------- template of the widget management class
Class CreationPolicy = MallocCreator, template
Class Container = ContainerVec> class WidgetManager: public CreationPolicy
{Public: typedef CreationPolicy
BaseClass; T * create () {T * tmp = BaseClass: create (); mContainer. push (tmp); return tmp;} private: Container
MContainer;}; // the greatest power of policies is that they can be mixed with each other // -------------------------------------------------------------------------------- typedef WidgetManager
BoxWidgetManager; typedef WidgetManager
SliderWidgetManager; // using int main () {BoxWidgetManager boxWidgetManager; BoxWidget * boxWidget = boxWidgetManager. create (); system ("pause ");}
What is Policy-based programming?
1. The replicies mechanism is composed of templates and multi-inheritance.
2. the so-called policy is used to define an interface of class or class template. This interface consists of one or all of the member functions, or member variables.
3. The policy interface is loose than the traditional class interface (virtual function) Because IES is syntax oriented rather than signature oriented ). That is to say, the above createpolicy clearly defines how to construct a class that complies with its specifications, rather than "What functions must be implemented ". Createpolicy does not specify whether create () is virtual or static. It only requires that the create FUNCTION be defined.
4. If a template uses policies, we call it host class, as shown in the widgetmanager above.
Policy class destructor
1. In most cases, the host class will be derived from some policies in the form of public inheritance. Therefore, you can convert a host class to a policy class and delete the pointer later.
Unless the policy class defines a virtual destructor, deleting a pointer to the policy class will cause a problem (at least this will cause the host class destructor not to be called)
2. If the policy class destructor is defined as a virtual destructor, it will impede the static connection feature of the policy and affect the execution efficiency. (Introducing a vptr also brings additional overhead), so try to avoid virtual destructor.
3. Many policy classes have no data members. They are purely a standard action. policy class should adopt a lightweight and efficient solution ------ define a non-vritual protected destructor. This ensures that only the successor can destroy this policy object.
Achieve selective functions through incomplete uniqueness
1. it means that if the class template has a member function that has never been used, it will not be implemented by the compiler.
Custom structure with policy class
Policy class can be used to customize behaviors, such as create and structure. This important property makes policy-based design go beyond the simple type generalization, which is superior to the container class. (The above container policy)
Next step: c ++ template traits