This should be the last one of this series. After so much annotation, other codes should have no difficulty in grammar. The rest is that everyone has come to "MODERN C Desing" ideas and use it.
// Last Update: June 20, 2001
#ifndef AbstractFactory_inc_ # define AbstractFactory_inc_
#include "typelist.h" #include "typemanip.h" #include "hierarchygeneratrs.h"
#include
Namespace loki {
// class template AbstractFactoryUnit // The building block of an Abstract Factory // WQ Note: The definition of a factory interface, which is implemented by the user is completed, and as a parameter template abtractfactory of class AbstractFactoryUnit {public: virtual T * DOCREATE (Type2Type ) = 0; // WQ Note: Due to the type of inter-type, note that it is in Overriding: GenscatterHierarchy's multiple Unit will constitute overloading, and have the same name mask effect . Virtual ~ AbstractFactoryUnit () {}};
// Class Template AbstractFactory // Defines An Abstract Factory Interface Starting from a Typelist
Template Class Unit = AbstractFactoryUnit // WQ Note: Note this, not TUPLEUNIT type, cannot be converted to T type. > Class AbstractFactory: Public GenScatterHierarchy // WQ Note: Please refer to GenScatterHierarchy's explanation, then add the docreate function. {Public: typef tlist product1; template t * create () // WQ Note: The derived class with the same name function masks the base class version, so I played a template skill. Note that the mask is visibility without preventing Overriding. // WQ Note: If this function is called, it cannot be derived, only Create () mode can be called. {Unit & Unit = * this; // WQ Note: T should be a member in TLIST, otherwise it will throw an exception Return Unit.docreate (Type2Type ()); // WQ Note: Avoid Various conversions on types ensure the above annotations. // WQ Note: This is the "public non-virtual interface" in the "Dialog" series in Herb Sutter, which is a lot of experience. // WQ Note: After these two sentences are combined, the optional docreate method only left, reaching the most accurate factory method to construct the effect of the object. In the traditional method, we need to numbered the type, and select the method with Switch ... case. }}; // Class Template OpnewFactoryUnit // Creates An Object by Invoking The New Operator
Template // WQ Note: Typical implementation of ConcreteProduct is below. Class OpnewFactoryUnit: Public Base // WQ Note: Be sure to take care of its inheritance map. {TypeDef TypeName Base :: ProductList BaseProductList; protected: typeproductlist :: tail product1; // wq Note: This typedef is also recursive! The end point is root (ie AbstractFact). This root is a decreasing recursive, OpnewFactoryUnit is the outermost layer of only TN, OpNewFactoryUnit is the T1 ... TN Typelist. (Note that this inner / outer layer is only illustrative, not exactly vocabulary.) Public: typedef typename BaseProductList :: Head AbstractProduct; ConcreteProduct * DoCreate (Type2Type ) // WQ Note: ConcreteProduct recursion is incremented, outermost layer Is T1, the innermost layer is TN, so if the Typelist it uses, the outermost layer is Tn, the innermost layer is T1, just as the AbstractProduct order! {Return new ConcreteProduct;}}; // class template PrototypeFactoryUnit // Creates an object by cloning a prototype // There is a difference between the implementation herein and the one described // in the book: GetPrototype and SetPrototype use the helper friend / . / functions DoGetPrototype and DoSetPrototype the friend functions avoid // name hiding issues Plus, GetPrototype takes a reference to pointer // instead of returning the pointer by value.//WQ Note:. Unit for GenLinearHierarchy use the same form prototype plant. However, it is required that the type in TypeList must provide a Clone function. template class PrototypeFactoryUnit: public Base {typedef typename Base :: ProductList BaseProductList; protected: typedef typename BaseProductList :: Tail ProductList;
Public: TypeDef TypeName BaseProductList :: Head AbstractProduct;
PrototypeFactoryUnit (AbstractProduct * p = 0): pPrototype_ (p) {} friend void DoGetPrototype (const PrototypeFactoryUnit & me, AbstractProduct * & pPrototype) {pPrototype = me.pPrototype_;} // WQ NOTE: ah sorry, I have not found this Syntax, but according to the relevant principles, this syntax is to be established, and it is speculated that the following is the function of the declaration. But with it, it will make the inline function becomes a non-class! Just worry about its visibility, and it is estimated that it is still inline, and it cannot take its address casually. friend void DoSetPrototype (PrototypeFactoryUnit & me, AbstractProduct * pObj) {me.pPrototype_ = pObj;} template void GetPrototype (AbstractProduct * & p) {return DoGetPrototype (* this, p);} template void SetPrototype (U * pObj) {DoSetPrototype (* this, pObj);} AbstractProduct * DoCreate (Type2Type ) {assert (pPrototype_); return pPrototype _-> Clone ();} private: AbstractProduct * pPrototype_;}; // class Template ConcreteFactory // Implements An AbstractFactory Interface
template class Creator = OpNewFactoryUnit, class TList = typename AbstractFact :: ProductList> class ConcreteFactory: public GenLinearHierarchy :: Result, Creator, AbstractFact> // WQ Note: It has been in front of its reasons. {Public: typedef typename AbstractFact :: ProductList ProductList; typedef TList ConcreteProductList;}; // WQ Note: To sum up: the realization, the actual plant must be derived from AbstractFactory, and all versions of DoCreate > () method Implementation; in the form of Create (); } // Namespace Loki // Change Log: // June 20, 2001: Ported by Nick Thurn To GCC 2.95.3. Kudos, Nick !!!
#endif // AbstractFactory_inc_