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

Loki库读解5(完):AbstractFactory.h读注 (转)[@more@]

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

// Last update: June 20, 2001

#ifndef ABSTRACTFACTORY_INC_
#define ABSTRACTFACTORY_INC_

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

#include

namespace Loki
{


// class template AbstractFactoryUnit
// The building block of an Abstract Factory

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


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

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

  }
  };
 

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

  template //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)
//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 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
  void GetPrototype(AbstractProduct*& p)
  { return DoGetPrototype(*this, p); }
 
  template
  void SetPrototype(U* pObj)
  { DoSetPrototype(*this, pObj); }
 
  AbstractProduct* DoCreate(Type2Type)
  {
  assert(pPrototype_);
  return pPrototype_->Clone();
  }
 
  private:
  AbstractProduct* pPrototype_;
  };


// class template ConcreteFactory
// Implements an AbstractFactory interface

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


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

#endif // ABSTRACTFACTORY_INC_


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752019/viewspace-975302/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752019/viewspace-975302/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值