Loki庫讀解5(完):AbstractFactory.h讀注 (轉)
這應該是本系列的最後一篇了吧。有這麼多註解後,其它程式碼在語法上應該不存在困難了。剩下的,就是大家來多多領會《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
名掩蓋效應。
virtual ~AbstractFactoryUnit() {}
};
////////////////////////////////////////////////////////////////////////////////
// class template AbstractFactory
// Defines an Abstract Factory interface starting from a typelist
////////////////////////////////////////////////////////////////////////////////
template
<
class TList,//此變數名起得不好,BCB用掉了。
template
>
class AbstractFactory : public GenScatterHierarchy
{
public:
typedef TList ProductList;
template
Create()//WQ注:派生類同名函式掩蓋基類版本,這兒於是玩了個模板技巧。注意,掩蓋的是可見性而不阻止overriding。
//WQ注:這個函式時沒法型別推導的,只能Create
{
Unit
return unit.DoCreate(Type2Type
//WQ注:這是Herb Sutter的"對話"系列中講的"公有非虛介面調私有虛實現",可去找來多多體會。
//WQ注:這兩句話結合後,可選的DoCreate方法只剩一個了,達到了呼叫最精確的廠方法來構造的效果。傳統方法中,我們需要為型別進行編號,用switch…case來選擇方法。
}
};
////////////////////////////////////////////////////////////////////////////////
// class template OpNewFactoryUnit
// Creates an by invoking the new operator
////////////////////////////////////////////////////////////////////////////////
template
class OpNewFactoryUnit : public Base//WQ注:一定要仔細參考它的繼承圖。
{
typedef typename Base::ProductList BaseProductList;
protected:
typedef typename BaseProductList::Tail ProductList;
//WQ注:這個typedef也是遞迴的!結束點為(即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 FactoryUnit
// 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 TList = typename AbstractFact::ProductList
>
class ConcreteFactory
: public GenLinearHierarchy<
typename TL::Reverse
//WQ注:它的反序原因在前面已經講了。
{
public:
typedef typename AbstractFact::ProductList ProductList;
typedef TList ConcreteProductList;
};
//WQ注:總結一下:實現時,必須從AbstractFactory派生實際廠,並提供所有版本的DoCreate
} // 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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 讀完《程式碼大全》
- 圖解Transformer,讀完這篇就夠了圖解ORM
- 2019年讀完的書
- 2017年讀完的書
- 思否講堂新版上線,TypeScript完全解讀26課時完更,這些好課值得關注!TypeScript
- 前端解讀控制反轉(IOC)前端
- 《心流》——每天十分鐘,解讀完本書
- 5G態勢解讀
- 資料庫規約解讀資料庫
- 2020年讀完的書:108本
- 2020年讀完的11本書
- 2012-2017年讀完的書
- Vue 原始碼解讀(5)—— 全域性 APIVue原始碼API
- 分散式系統關注點——360°全方位解讀「快取」分散式快取
- 3 個技巧讓你在 30 分鐘內讀完一本書,一年讀完 100 本書
- 精讀《利用 GPT 解讀 PDF》GPT
- basictracer-go原始碼閱讀——examples(完結)Go原始碼
- 使用免費的OA系統靠譜嗎?讀完更瞭解OA
- 解讀圖資料庫技術路線資料庫
- HTML5權威指南讀書筆記25(完結)(第37章)--使用拖放HTML筆記
- 【Mysql】資料庫事務,髒讀、幻讀、不可重複讀MySql資料庫
- CausalTAD解讀
- Redux解讀Redux
- 線上MySQL讀寫分離,出現寫完讀不到問題如何解決MySql
- 閱讀筆記5筆記
- LLaMA 3 原始碼解讀-大語言模型5原始碼模型
- PostgreSQL 原始碼解讀(5)- 插入資料#4(ExecInsert)SQL原始碼
- PostgreSQL 原始碼解讀(6)- 插入資料#5(ExecModifyTable)SQL原始碼
- [swift進階]的讀書筆記寫完啦~Swift筆記
- OceanBase 原始碼解讀(七):一文讀懂資料庫索引實現原理原始碼資料庫索引
- 一文詳解髒讀、不可重複讀、幻讀
- 分析師解讀記憶體資料庫MemSQLSP記憶體資料庫SQL
- [轉帖]記憶體分析之GCViewer詳細解讀記憶體GCView
- JDK原始碼閱讀(5):HashTable類閱讀筆記JDK原始碼筆記
- PostgreSQL 原始碼解讀(234)- 查詢#127(NOT IN實現#5)SQL原始碼
- PostgreSQL 原始碼解讀(197)- 查詢#112(排序#5 - mergeruns)SQL原始碼排序
- 「模型解讀」歷數GAN的5大基本結構模型
- PostgreSQL 原始碼解讀(253)- PG 14(Improving connection scalability)#5SQL原始碼
- 讀《圖解HTTP》圖解HTTP