gnugk5.5原始碼分析(3)之模板工廠
前言
如果按前面第二節的內容,這節應該是接著講Ras或者H225的socket收到包後,怎麼去處理的事項。但是在開始講如何資料包之前,我想先講一下gnugk的模板工廠定義與實現。之所以要這樣,是因為在接下來的很多地方都會用到這個實現,所以感覺應該先講講。
簡單來說,gnugk的模板工廠定義,就是定義了四類工廠方法,不帶引數、帶1個引數、帶2個引數、帶3個引數的的工廠,這裡講到的工廠,是一種設計方法,工廠可以構造生成產品;而採用模板,可以更加靈活的定義工廠的型別。在gnugk中這個實現被定義在factory.h檔案中。
一、函式構造器Functor系列
template<typename R>
struct Functor {
typedef R result_type;
virtual ~Functor() { }
};
從上可以看到最基礎抽象的函式構造器Functor,模板接受一個引數型別R作為返回型別,並且只定義了一個虛析構~Functor。接下來看下它的子類。
template<typename R>
struct Functor0 : public Functor<R> {
virtual R operator()() const = 0;
};
template<typename R, typename T1>
struct Functor1 : public Functor<R> {
typedef T1 argument_type;
virtual R operator()(T1) const = 0;
};
template<typename R, typename T1, typename T2>
struct Functor2 : public Functor<R> {
typedef T1 first_argument_type;
typedef T2 second_argument_type;
virtual R operator()(T1, T2) const = 0;
};
template<typename R, typename T1, typename T2, typename T3>
struct Functor3 : public Functor<R> {
typedef T1 first_argument_type;
typedef T2 second_argument_type;
typedef T3 third_argument_type;
virtual R operator()(T1, T2, T3) const = 0;
};
可以看到有四個子類繼承自Functor,分別是Functor0、Functor1、Functor2、Functor3;這裡的所謂的0,1,2,3的命名,也是指示了每個構造器可接受的引數的個數。我們以Functor0為例來說明下。
template<typename R>
struct Functor0 : public Functor<R> {
virtual R operator()() const = 0;
};
Functor0繼承自Functor,也是隻接受一個引數型別R,作為返回值,但是Functor0新新增定義了一個純虛擬函式,virtual R operator()() const = 0,實際上是一個例項呼叫運算子();這個操作符的使用場景是,假設現有一個類A,例項化A a; 當呼叫a()時,即呼叫到了這個操作符;
綜上,Functor0的行為是接受一個引數型別R,當返回值;並協定其子類需要過載實現呼叫運算子,且這個呼叫運算子是無參的。
採用同樣的方法,可以看出Functor1、Functor2、Functor3相對於Functor0,只是協議這個呼叫運算子,分別需要接受1個、2個、3個引數而已。
二、模板工廠類Factory
這裡先整體說明一下這個模板工廠類Factory的實現功能:
1 接受兩個引數型別,第一個是類型別,作為產品Product,第二個是這個產品的標識Identifier,預設型別為const char *;
2 定義Creator0、Creator1、Creator2、Creator3分別對應於Functor0、Functor1、Functor2、Functor3,支援無參,帶1個引數、帶2個引數、帶3個引數的產品構造器;
3 每個型別的產品構造器都在模板特化時,註冊儲存相對應的構造器,以便於後續在呼叫Create的方法時,能正確查詢並構造相應的產品例項。
未完待續。。。
相關文章
- Vue3原始碼分析之compositionApiVue原始碼API
- 集合原始碼分析[3]-ArrayList 原始碼分析原始碼
- Guava 原始碼分析之 EventBus 原始碼分析Guava原始碼
- Android 原始碼分析之 AsyncTask 原始碼分析Android原始碼
- 深度 Mybatis 3 原始碼分析(一)SqlSessionFactoryBuilder原始碼分析MyBatis原始碼SQLSessionUI
- EOS原始碼分析(3)案例分析原始碼
- 原始碼分析之 HashMap原始碼HashMap
- 原始碼分析之 LinkedList原始碼
- 原始碼|jdk原始碼之HashMap分析(一)原始碼JDKHashMap
- 原始碼|jdk原始碼之HashMap分析(二)原始碼JDKHashMap
- 原始碼中的設計模式--工廠模式原始碼設計模式
- 設計模式(十四)——模板模式(SpringIOC原始碼分析)設計模式Spring原始碼
- 3.java設計模式之工廠模式Java設計模式
- 工廠模式之簡單工廠模式模式
- 死磕 jdk原始碼之HashMap原始碼分析JDK原始碼HashMap
- Android 原始碼分析之 EventBus 的原始碼解析Android原始碼
- lodash原始碼分析之isArguments原始碼
- Envoy原始碼分析之Dispatcher原始碼
- Fresco原始碼分析之DraweeView原始碼View
- Netty原始碼分析之LengthFieldBasedFrameDecoderNetty原始碼
- RecyclerView之SnapHelper原始碼分析View原始碼
- tornado 原始碼之 coroutine 分析原始碼
- lodash原始碼分析之isObjectLike原始碼Object
- OpenGL 之 GPUImage 原始碼分析GPUUI原始碼
- jdk原始碼分析之TreeMapJDK原始碼
- 原始碼分析Kafka之Producer原始碼Kafka
- DRF之Response原始碼分析原始碼
- Spring AOP之原始碼分析Spring原始碼
- BlueStore原始碼分析之FreelistManager原始碼
- JUC之ReentrantLock原始碼分析ReentrantLock原始碼
- JUC之CountDownLatch原始碼分析CountDownLatch原始碼
- Fresco原始碼分析之Hierarchy原始碼
- Dubbo之SPI原始碼分析原始碼
- MongoDB原始碼分析之MongosXFMongoDB原始碼
- Flutter原始碼分析之InheritedWidgetFlutter原始碼
- Redux原始碼分析之createStoreRedux原始碼
- Java原始碼分析:Guava之不可變集合ImmutableMap的原始碼分析Java原始碼Guava
- Thinkphp3原始碼分析(2)PHP原始碼