完成代码 见
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);
//1
Monster *s;
s = easyFactory->Create<Monster>();
delete s;
//2
AbstractFactoryUnit<Soldier> & soldier_V = *easyFactory;
AbstractFactoryUnit<Monster> & monster_V = *easyFactory;
AbstractFactoryUnit<SuperMonster> & superMonster_V = *easyFactory;
}
下图 为 两个类 的继承关系图