c++ 模板之 抽象工厂

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuyingqingfen/article/details/43938851


完成代码 见 

 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;
 
}


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






猜你喜欢

转载自blog.csdn.net/zhuyingqingfen/article/details/43938851
今日推荐