gnugk5.5原始碼分析(3)之模板工廠

StarSky_Ye發表於2020-11-19

前言

如果按前面第二節的內容,這節應該是接著講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的方法時,能正確查詢並構造相應的產品例項。

未完待續。。。

相關文章