Loki库读解5(完):AbstractFactory.h读注

原创 2002年11月10日 11:44:00

这应该是本系列的最后一篇了吧。有这么多注解后,其它代码在语法上应该不存在困难了。剩下的,就是大家来多多领会《Modern C++Desing》的思想,并运用了。

// Last update: June 20, 2001

#ifndef ABSTRACTFACTORY_INC_
#define ABSTRACTFACTORY_INC_

#include "Typelist.h"
#include "TypeManip.h"
#include "HierarchyGenerators.h"

#include <cassert>

namespace Loki
{

////////////////////////////////////////////////////////////////////////////////
// class template AbstractFactoryUnit
// The building block of an Abstract Factory
////////////////////////////////////////////////////////////////////////////////
//WQ注:定义了一个厂接口,而其实现由用户自己完成,并作为abtractfactory的参数
    template <class T>
    class AbstractFactoryUnit
    {
    public:
        virtual T* DoCreate(Type2Type<T>) = 0;//WQ注:由于类型间去耦合,请注意它在overriding时的微妙效果:GenScatterHierarchy的多个Unit<T>间将构成overloading,并且有同
名掩盖效应。
        virtual ~AbstractFactoryUnit() {}
    };

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

    template
    <
        class TList,//此变量名起得不好,BCB用掉了。
        template <class> class Unit = AbstractFactoryUnit//WQ注:注意这个,不是TupleUnit<T>类型,无法自动转换到T类型。
    >
    class AbstractFactory : public GenScatterHierarchy<TList,
Unit>//WQ注:请参考GenScatterHierarchy的讲解图,这时要将DoCreate函数加上了。
    {
    public:
        typedef TList ProductList;
      
        template <class T> T*
Create()//WQ注:派生类同名函数掩盖基类版本,这儿于是玩了个模板技巧。注意,掩盖的是可见性而不阻止overriding。
//WQ注:这个函数调用时没法类型推导的,只能Create<T>()方式调用。
        {
            Unit<T>& unit = *this; //WQ注:T应该为Tlist中的一员,否则会抛编译异常
return unit.DoCreate(Type2Type<T>());//WQ注:避免了类型上的各种转换,确保实现了上面的注解。
//WQ注:这是Herb Sutter的"对话"系列中讲的"公有非虚接口调私有虚实现",可去找来多多体会。
//WQ注:这两句话结合后,可选的DoCreate方法只剩一个了,达到了调用最精确的厂方法来构造对象的效果。传统方法中,我们需要为类型进行编号,用switch…case来选择方法。

        }
    };
  
////////////////////////////////////////////////////////////////////////////////
// class template OpNewFactoryUnit
// Creates an object by invoking the new operator
////////////////////////////////////////////////////////////////////////////////

    template <class ConcreteProduct, class Base>//WQ注:ConcreteProduct的典型实现就在下面。
    class OpNewFactoryUnit : public Base//WQ注:一定要仔细参考它的继承图。
    {
        typedef typename Base::ProductList BaseProductList;
      
    protected:
        typedef typename BaseProductList::Tail ProductList;
  
//WQ注:这个typedef也是递归的!结束点为root(即AbstractFact)。此root是递减递归,OpNewFactoryUnit最外层时它只一个Tn,OpNewFactoryUnit最里面时它是T1…Tn的TypeList。(注意,这个内/外层仅为示意,并非精确词汇。)
    public:
        typedef typename BaseProductList::Head AbstractProduct;
        ConcreteProduct* DoCreate(Type2Type<AbstractProduct>)
//WQ注:ConcreteProduct是递增递归,最外层时是T1,最内层时是Tn,所以,如果它所用的TypeList反有下序的话,则最外层时是Tn,最内层时是T1,正好和AbstractProduct顺序相同!
        {
            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注:同样供GenLinearHierarchy的Unit使用,形成原型厂。只不过要求TypeList中的类型都必须提供Clone函数。
    template <class ConcreteProduct, class Base>
    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注:抱歉啊,我没查到这种语法,但根据相关原则,这种语法是可以成立的,推测如下:friend本身不兼具申明的功能。但有了它,将使得内联的函数变成非类成员了!只是担心它的可见性,而且估计它仍然是内联的,不能随便取其地址。
        friend void DoSetPrototype(PrototypeFactoryUnit& me,
            AbstractProduct* pObj)
        { me.pPrototype_ = pObj; }
      
        template <class U>
        void GetPrototype(AbstractProduct*& p)
        { return DoGetPrototype(*this, p); }
      
        template <class U>
        void SetPrototype(U* pObj)
        { DoSetPrototype(*this, pObj); }
      
        AbstractProduct* DoCreate(Type2Type<AbstractProduct>)
        {
            assert(pPrototype_);
            return pPrototype_->Clone();
        }
      
    private:
        AbstractProduct* pPrototype_;
    };

////////////////////////////////////////////////////////////////////////////////
// class template ConcreteFactory
// Implements an AbstractFactory interface
////////////////////////////////////////////////////////////////////////////////

    template
    <
        class AbstractFact,
        template <class, class> class Creator = OpNewFactoryUnit,
        class TList = typename AbstractFact::ProductList
    >
    class ConcreteFactory
        : public GenLinearHierarchy<
typename TL::Reverse<TList>::Result, Creator, AbstractFact>
//WQ注:它的反序原因在前面已经讲了。
    {
    public:
        typedef typename AbstractFact::ProductList ProductList;
        typedef TList ConcreteProductList;
    };
//WQ注:总结一下:实现时,必须从AbstractFactory派生实际厂,并提供所有版本的DoCreate<Type2Type<T>>()方法的实现;使用时,使用Create<T>();的形式。
} // namespace Loki

////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////

#endif // ABSTRACTFACTORY_INC_

《Modern C++ Design》Loki库读解四:HierarchyGenerators.h读注

Loki库读解四:HierarchyGenerators.h读注这中间的每一行代码都是懂的,使用它的例子也看过了,可还是没明白应该怎样使用这东西。还望有人能答了。///////////////////...
  • taodm
  • taodm
  • 2002年10月28日 09:37
  • 1597

《Modern C++ Design》Loki库源码读解随想

《Modern C++ Design》Loki库源码读解随想大牛Andrei Alexandrescu的《Modern C++ Design》讨论的是C++语言的最前沿研究:generative pr...
  • taodm
  • taodm
  • 2002年07月23日 10:52
  • 7373

Loki库使用介绍

[-] C设计模式类库 Loki介绍与用法 编译 Singleton模式单件模式 头文件类型定义示例代码 对象工厂 Object Factory 头文件类型成员方法示例代码 Abstract ...
  • zhu2695
  • zhu2695
  • 2016年04月25日 22:05
  • 1151

Loki库使用(1)

Loki库使用(1) 2012-11-07 16:44 7090人阅读 评论(2) 收藏 举报 目录(?)[+] C++设计模式类库 Loki介绍与用法 Loki是由Andrei编写的一个与《...
  • zdy0_2004
  • zdy0_2004
  • 2014年10月20日 21:31
  • 1361

【C++】Loki库源码读解随想

《Modern C++ Design》Loki库源码读解随想 大牛Andrei Alexandrescu的《Modern C++ Design》讨论的是C++语言的最前沿研究:generative ...
  • little_stupid_child
  • little_stupid_child
  • 2017年01月14日 18:28
  • 121

关于模板偏特化,模板递归,及Loki之Typelist和一些感悟

一直以来,在大多数情况下,递归被看做是低效率的表现,从学习编程开始,就一直被教导,不用或至少少用递归。但在模板编程中,递归和模板偏特化联合,起了相当大的作用。可以说,没有递归,在很大程度上,模板编程便...
  • kewing
  • kewing
  • 2010年10月23日 11:39
  • 2621

C++三大库boost、loki、stlport

转: STL是一个标准,各商家根据这个标准开发了各自的STL版本。而在这形形色色的STL版本中,SGI STL无疑是最引人瞩目的一个。这当然是因为这个STL产品系出名门,其设计和编写者名单中,Ale...
  • zww0815
  • zww0815
  • 2016年04月28日 16:14
  • 1932

【设计模式】--C++设计模式类库 Loki介绍与用法

http://www.usidcbbs.com/simple/?t2428.html http://book.douban.com/subject/1119904/ C++设计模式类库 Lok...
  • Witch_Soya
  • Witch_Soya
  • 2012年05月29日 14:11
  • 3302

Loki库读解-扩展TypeList:Typelist生成器、MaxSizeOf

Loki中的TYPELIST_**宏还是太难用了,因为无法支持不定参数。借鉴于BOOST中的Tuple的想法,实现了这个Typelist_Maker:template         class T6...
  • taodm
  • taodm
  • 2004年04月08日 18:51
  • 1678

LOKI库

递归之美 - Loki库TypeList源码剖析 转载于 http://blog.sina.com.cn/s/blog_45497dfa0100ppbp.htmlLOKI库读解:AbstractF...
  • xcw_1987
  • xcw_1987
  • 2016年12月22日 17:39
  • 78
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Loki库读解5(完):AbstractFactory.h读注
举报原因:
原因补充:

(最多只允许输入30个字)