程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++ 模板之 抽象工廠

c++ 模板之 抽象工廠

編輯:C++入門知識

c++ 模板之 抽象工廠


 

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 
#include 

namespace Loki
{

////////////////////////////////////////////////////////////////////////////////
//Type2Type 用於消除歧義,因為同一個繼承體會有多個AbstractFactoryUnit的具現體
//如:AbstractFactoryUnit ,AbstractFactoryUnit等
//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 AbstractFactoryUnit
    {
    public:
        virtual T* DoCreate(Type2Type) = 0;
        virtual ~AbstractFactoryUnit() {} 
    };

////////////////////////////////////////////////////////////////////////////////
// class template AbstractFactory
// Defines an Abstract Factory interface starting from a typelist
////////////////////////////////////////////////////////////////////////////////

    template
    <
        class TList,
        template  class Unit = AbstractFactoryUnit
    >
    class AbstractFactory : public GenScatterHierarchy
    {
    public:
        typedef TList ProductList;
        
        template  T* Create()
        {
            Unit& unit = *this;
            return unit.DoCreate(Type2Type());
        }
    };
    
////////////////////////////////////////////////////////////////////////////////
// class template OpNewFactoryUnit
// Creates an object by invoking the new operator
////////////////////////////////////////////////////////////////////////////////

    template 
    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抽象產品,ConcreteProduct具體產品,同Soldier和SillySoldier的關系
			std::cout<<基類:<)中的AbstractProduct的順序相反,所以需要Reverse一下

	 當然也可以修改OpNewFactoryUnit 而不翻轉ConcreteFactory中的TList 修改成如下:
	 typedef typename Base::ProductList BaseProductList;  
	 protected:
	 typedef typename Reverse%3CBaseProductList%3E::Result::Tail>::Result ProductList;
	 public:
	 typedef typename Reverse::Result::Head AbstractProduct;
	 不過這種設計不太好,因為每個Creator都要處理這種翻轉情況,不如在ConcreteFactory類中一下徹底解決問題好。


*/
////////////////////////////////////////////////////////////////////////////////

    template
    <
        class AbstractFact,
        template  class Creator = OpNewFactoryUnit,
        class TList = typename AbstractFact::ProductList
    >
	class ConcreteFactory
		: public GenLinearHierarchy::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 AbstractEnemyFactory;

	typedef ConcreteFactory EasyLevelEnemyFactory;
	typedef ConcreteFactory HardLevelEnemyFactory;
	
 
	std::auto_ptr easyFactory(new EasyLevelEnemyFactory);
	std::auto_ptr hardFactory(new HardLevelEnemyFactory);

	
	//1
	Monster *s;
	s = easyFactory->Create();
	delete s;
	//2
 
	AbstractFactoryUnit & soldier_V = *easyFactory;
	AbstractFactoryUnit & monster_V = *easyFactory;
	AbstractFactoryUnit & superMonster_V = *easyFactory;
 
}


 

下圖 為 兩個類 的繼承關系圖

/

 

 

/

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved