c++ 模板之 抽象工厂

来源:互联网 发布:钢材贸易进销存软件 编辑:程序博客网 时间:2024/06/05 16:42


完成代码 见 

 http://download.csdn.net/detail/zhuyingqingfen/8457091

1. 设计模式中抽象工厂的泛型 实现

2. c++ 自动生成模板代码 的例子 具体实现见:c++ 泛型编程 之 自动生成代码




////////////////////////////////////////////////////////////////////////////////// The Loki Library// Copyright (c) 2001 by Andrei Alexandrescu// This code accompanies the book:// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.// Permission to use, copy, modify, distribute and sell this software for any //     purpose is hereby granted without fee, provided that the above copyright //     notice appear in all copies and that both that copyright notice and this //     permission notice appear in supporting documentation.// The author or Addison-Wesley Longman make no representations about the //     suitability of this software for any purpose. It is provided "as is" //     without express or implied warranty.////////////////////////////////////////////////////////////////////////////////#ifndef LOKI_ABSTRACTFACTORY_INC_#define LOKI_ABSTRACTFACTORY_INC_// $Id: AbstractFactory.h 771 2006-10-27 18:05:03Z clitte_bbt $#include "HierarchyGenerators.h"#include "typelists.h"#include <cassert>#include <iostream>namespace Loki{//////////////////////////////////////////////////////////////////////////////////Type2Type<T> 用于消除歧义,因为同一个继承体会有多个AbstractFactoryUnit的具现体//如:AbstractFactoryUnit<A> ,AbstractFactoryUnit<B>等//DoCreate这个函数返回的并不是一个常类型,因为T为可变的//在c++中,你可以"返回型别为Pointer to Derived class "的函数改写(overide)为“返回// pointer to base class"的函数。这个就是”协变式返回型别(covariant return types)/*class A{public:virtual A * ff() = 0;};class B:public A{public:B * ff(){return this;}};使用:B b;*/////////////////////////////////////////////////////////////////////////////////    template <class T>    class AbstractFactoryUnit    {    public:        virtual T* DoCreate(Type2Type<T>) = 0;        virtual ~AbstractFactoryUnit() {}     };////////////////////////////////////////////////////////////////////////////////// class template AbstractFactory// Defines an Abstract Factory interface starting from a typelist////////////////////////////////////////////////////////////////////////////////    template    <        class TList,        template <class> class Unit = AbstractFactoryUnit    >    class AbstractFactory : public GenScatterHierarchy<TList, Unit>    {    public:        typedef TList ProductList;                template <class T> T* Create()        {            Unit<T>& unit = *this;            return unit.DoCreate(Type2Type<T>());        }    };    ////////////////////////////////////////////////////////////////////////////////// class template OpNewFactoryUnit// Creates an object by invoking the new operator////////////////////////////////////////////////////////////////////////////////    template <class ConcreteProduct, class Base>    class OpNewFactoryUnit : public Base    {        typedef typename Base::ProductList BaseProductList;      protected:        typedef typename BaseProductList::Tail ProductList;    public:        typedef typename BaseProductList::Head AbstractProduct;        ConcreteProduct* DoCreate(Type2Type<AbstractProduct>)        {//AbstractProduct抽象产品,ConcreteProduct具体产品,同Soldier和SillySoldier的关系std::cout<<"基类:"<<typeid(Base).name()<<std::endl;std::cout<<"基类产品:"<<typeid(BaseProductList).name()<<std::endl;std::cout<<"抽象名称:"<<typeid(AbstractProduct).name()<<std::endl;std::cout<<"具体实现:"<<typeid(ConcreteProduct).name()<<std::endl;std::cout<<"剩余的:"<<typeid(ProductList).name()<<std::endl;            return new ConcreteProduct;        }    }; ////////////////////////////////////////////////////////////////////////////////// AbstractFact:提供的是“欲实现的abstract factory接口”,并隐式提供了一组产品(products)// Creator: 是个Policy,规定如何实际生成对象。// TList: 提供了“这个factory所要生成的concrete classes”的集合。//   这个typelist中的每一个具象型别都有一个abstractFactory的typelist中//         具有相同索引的抽象型别。// 使用Reverse的原因:/*OpNewFactoryUnit 生成重载函数DoCreate是从上到下的顺序生成的(体现在ProductList上,因为继承类都是从父类 找到Head,然后再把Tail传递给下面的类。如果BaseProductList是Soldier, Monster, SuperMonster,那么 子类的AbstractProduct是Soldier,ProductList是Monster, SuperMonster,再往下继承AbstractProduct是Monster ProductList是SuperMonster,而ConcreteFactory 把引数TList 传递给OpNewFactoryUnit中的ConcreteProduct引数 是从下到上的,如果是ConcreteFactory中的TList是SillySoldier, SillyMonster, SillySuperMonster,那么 ConcreteFactory的继承关系树中从下到上OpNewFactoryUnit的ConcreteProduct依次是SillySoldier,SillyMonster,SillySuperMonster 这样正好和 DoCreate(Type2Type<AbstractProduct>)中的AbstractProduct的顺序相反,所以需要Reverse一下 当然也可以修改OpNewFactoryUnit 而不翻转ConcreteFactory中的TList 修改成如下: typedef typename Base::ProductList BaseProductList;   protected: typedef typename Reverse<typename Reverse<BaseProductList>::Result::Tail>::Result ProductList; public: typedef typename Reverse<BaseProductList>::Result::Head AbstractProduct; 不过这种设计不太好,因为每个Creator都要处理这种翻转情况,不如在ConcreteFactory类中一下彻底解决问题好。*/////////////////////////////////////////////////////////////////////////////////    template    <        class AbstractFact,        template <class, class> class Creator = OpNewFactoryUnit,        class TList = typename AbstractFact::ProductList    >class ConcreteFactory: public GenLinearHierarchy<typename Reverse<TList>::Result, Creator, AbstractFact>    {    public:typedef typename AbstractFact::ProductList ProductList;typedef TList ConcreteProductList;    };} // namespace Loki#endif // end file guardian

class Soldier { public: virtual ~Soldier() {} };class Monster { public: virtual ~Monster() {} };class SuperMonster { public: virtual ~SuperMonster() {} };class SillySoldier : public Soldier {};class SillyMonster : public Monster {};class SillySuperMonster : public SuperMonster {};class BadSoldier : public Soldier {};class BadMonster : public Monster {};class BadSuperMonster : public SuperMonster {};void abstractfactory_test(){using namespace Loki;typedef AbstractFactory<TYPELIST_3(Soldier, Monster, SuperMonster)> AbstractEnemyFactory;typedef ConcreteFactory<AbstractEnemyFactory, OpNewFactoryUnit,TYPELIST_3(SillySoldier, SillyMonster, SillySuperMonster)> EasyLevelEnemyFactory;typedef ConcreteFactory<AbstractEnemyFactory, OpNewFactoryUnit,TYPELIST_3(BadSoldier, BadMonster, BadSuperMonster)> HardLevelEnemyFactory; std::auto_ptr<AbstractEnemyFactory> easyFactory(new EasyLevelEnemyFactory);std::auto_ptr<AbstractEnemyFactory> hardFactory(new HardLevelEnemyFactory);//1Monster *s;s = easyFactory->Create<Monster>();delete s;//2 AbstractFactoryUnit<Soldier> & soldier_V = *easyFactory;AbstractFactoryUnit<Monster> & monster_V = *easyFactory;AbstractFactoryUnit<SuperMonster> & superMonster_V = *easyFactory; }


下图 为 两个类 的继承关系图






1 0
原创粉丝点击