1- 我們來(lái)確定我們的目標(biāo)
我們需要事先一個(gè)叫做xCreator的模板類(lèi),能夠根據(jù)一個(gè)基類(lèi)TBase實(shí)例化出一個(gè)構(gòu)造器類(lèi),能夠通過(guò)Support<TObject>()的形式來(lái)支持TBase的派生類(lèi)TObject,并能夠通過(guò) Create<TObject>() 的形式來(lái)構(gòu)造出這個(gè)TObject的對(duì)象。
2- 思考我們事先這個(gè)目標(biāo)的理論基礎(chǔ)
我們需要為每個(gè)TObject,創(chuàng)建一個(gè)單獨(dú)的內(nèi)部構(gòu)造器,在Support調(diào)用的時(shí)候,創(chuàng)建并存儲(chǔ)這個(gè)內(nèi)部構(gòu)造器。當(dāng)Create調(diào)用的時(shí)候,我們尋找這個(gè)內(nèi)部構(gòu)造器,并且通過(guò)這個(gè)構(gòu)造器構(gòu)造出TObject的對(duì)象。
3- 內(nèi)部構(gòu)造器
在設(shè)計(jì)內(nèi)部構(gòu)造器的時(shí)候,因?yàn)樾枰粋€(gè)通用的返回TBase的接口,所以,我們把這個(gè)接口做成一個(gè)虛接口。
class xBaseCreator


{
public:
virtual TBase * CreateObject() = 0;
};
接下來(lái),就是用模板來(lái)實(shí)現(xiàn)TObject的構(gòu)造器了。
template <class TObject>
class xObjectCreator : public xBaseCreator


{
public:

TBase * CreateObject()
{ return new TObject();}
};
有了內(nèi)部的構(gòu)造器,我們構(gòu)造出外部的框架xCreator
template <class TBase>
class xCreator


{
class xBaseCreator

{
public:
virtual TBase * NewObject() = 0;
};

template <class TObject>
class xObjectCreator : public xBaseCreator

{
public:

TBase * CreateObject()
{ return new TObject();}
};
public:
template <class TObject>
void Support()

{
}

template <class TObject>
TBase * Create()

{
}
};
現(xiàn)在,這個(gè)構(gòu)造器已經(jīng)有了雛形。
4- 實(shí)現(xiàn)Support
Support說(shuō)白了,就是通過(guò)TObject來(lái)創(chuàng)建一個(gè)內(nèi)部構(gòu)造器,并保存在xCreator<TBase>里面。
那么我們需要在這個(gè)框架里加入一個(gè)容器來(lái)存儲(chǔ)一系列的內(nèi)部構(gòu)造器。
xVector<xBaseCreator*> m_vInnerCreators;
這里用的xVector是xlibplus的一部分,實(shí)際上它表現(xiàn)的跟STL的vector很相似,可以互換使用。
下面就是Support的實(shí)際代碼,很簡(jiǎn)單的一句(沒(méi)有做一些安全性和重復(fù)的檢測(cè))
template <class TObject>
void Support()

{
m_vInnerCreators.push_back( new xObjectCreator<TObject>() );
}
5- 實(shí)現(xiàn)Create
Create是整個(gè)構(gòu)造器的重頭戲。我們需要找到一種方法,能夠通過(guò)TObject來(lái)找到它所對(duì)應(yīng)的內(nèi)部構(gòu)造器。
我們知道,同一個(gè)類(lèi)中的靜態(tài)成員的地址對(duì)于所有類(lèi)成員來(lái)說(shuō),是一個(gè)相同的固定的地址。這樣,這個(gè)地址,就可以標(biāo)示一個(gè)特定的類(lèi)。
然后,我們知道,模板參數(shù)相同的模板類(lèi)實(shí)例類(lèi),是同一個(gè)類(lèi)。
根據(jù)這兩個(gè),我們能夠設(shè)計(jì)一種方法,通過(guò)靜態(tài)成員的地址,來(lái)找到TObject對(duì)應(yīng)的內(nèi)部構(gòu)造器的方法。下面就是這種方法的代碼。
首先,修改xBaseCreator的接口,提供一個(gè)獲取類(lèi)的Code的接口,這個(gè)Code就是模板類(lèi)中的一個(gè)靜態(tài)變量的地址。
class xBaseCreator

{
public:
virtual TBase * CreateObject() = 0;
virtual void * GetClassCode() = 0;
};
然后,修改xObjectCreator,提供一個(gè)靜態(tài)變量,以及GetClassCode()的實(shí)現(xiàn)。
template <class TObject>
class xObjectCreator : public xBaseCreator

{
public:

static void * GetCode()
{
static int nClassCode = 0;
return &nClassCode;
}

void * GetClassCode()
{ return GetCode();}

TBase * CreateObject()
{ return new TObject();}
};
最后,我們把Create寫(xiě)好。
template <class TObject>
TBase * Create()

{
void * pClassCode = xObjectCreator<TObject>::GetCode();
for( int i = 0;i < m_vInnerCreators.size();i ++ )
if( m_vInnerCreators[i]->GetClassCode() == pClassCode )
return m_vInnerCreators[i]->CreateObject();
return NULL;
}
從代碼中可以看出整個(gè)方法都集中在這個(gè)Create里面的內(nèi)部構(gòu)造器搜索上面。這種方法有點(diǎn)類(lèi)似RTTI。
到現(xiàn)在為止,這個(gè)通用構(gòu)造器就基本完成了。代碼比較糙,只是用來(lái)說(shuō)明這個(gè)方法。至于刪除之類(lèi)的代碼,就比較簡(jiǎn)單了.
下面是完整的這個(gè)構(gòu)造器的代碼,以及測(cè)試代碼。
#include "stdafx.h"
#include <conio.h>


template <class TBase>
class xCreator


{
class xBaseCreator

{
public:
virtual TBase * CreateObject() = 0;
virtual void * GetClassCode() = 0;
};

template <class TObject>
class xObjectCreator : public xBaseCreator

{
public:

static void * GetCode()
{
static int nClassCode = 0;
return &nClassCode;
}

void * GetClassCode()
{ return GetCode();}

TBase * CreateObject()
{ return new TObject();}
};
xVector<xBaseCreator*> m_vInnerCreators;
public:
template <class TObject>
void Support()

{
m_vInnerCreators.push_back( new xObjectCreator<TObject>() );
}

template <class TObject>
TBase * Create()

{
void * pClassCode = xObjectCreator<TObject>::GetCode();
for( int i = 0;i < m_vInnerCreators.size();i ++ )
if( m_vInnerCreators[i]->GetClassCode() == pClassCode )
return m_vInnerCreators[i]->CreateObject();
return NULL;
}
};

class CBase


{
public:

virtual int GetCode() const
{ return 0;}
};

class CTest1 : public CBase


{
public:

virtual int GetCode() const
{ return 1;}
};

class CTest2 : public CBase


{
public:

virtual int GetCode() const
{ return 2;}
};

xCreator<CBase> testcreator;
int _tmain(int argc, _TCHAR* argv[])


{
testcreator.Support<CTest1>();
testcreator.Support<CTest2>();
CBase * p1 = testcreator.Create<CTest1>();
CBase * p2 = testcreator.Create<CTest2>();
printf( "code = %u / %u\n", p1->GetCode(), p2->GetCode() );
getch();
return 0;
}
我們需要事先一個(gè)叫做xCreator的模板類(lèi),能夠根據(jù)一個(gè)基類(lèi)TBase實(shí)例化出一個(gè)構(gòu)造器類(lèi),能夠通過(guò)Support<TObject>()的形式來(lái)支持TBase的派生類(lèi)TObject,并能夠通過(guò) Create<TObject>() 的形式來(lái)構(gòu)造出這個(gè)TObject的對(duì)象。
2- 思考我們事先這個(gè)目標(biāo)的理論基礎(chǔ)
我們需要為每個(gè)TObject,創(chuàng)建一個(gè)單獨(dú)的內(nèi)部構(gòu)造器,在Support調(diào)用的時(shí)候,創(chuàng)建并存儲(chǔ)這個(gè)內(nèi)部構(gòu)造器。當(dāng)Create調(diào)用的時(shí)候,我們尋找這個(gè)內(nèi)部構(gòu)造器,并且通過(guò)這個(gè)構(gòu)造器構(gòu)造出TObject的對(duì)象。
3- 內(nèi)部構(gòu)造器
在設(shè)計(jì)內(nèi)部構(gòu)造器的時(shí)候,因?yàn)樾枰粋€(gè)通用的返回TBase的接口,所以,我們把這個(gè)接口做成一個(gè)虛接口。
























































4- 實(shí)現(xiàn)Support
Support說(shuō)白了,就是通過(guò)TObject來(lái)創(chuàng)建一個(gè)內(nèi)部構(gòu)造器,并保存在xCreator<TBase>里面。
那么我們需要在這個(gè)框架里加入一個(gè)容器來(lái)存儲(chǔ)一系列的內(nèi)部構(gòu)造器。

下面就是Support的實(shí)際代碼,很簡(jiǎn)單的一句(沒(méi)有做一些安全性和重復(fù)的檢測(cè))







5- 實(shí)現(xiàn)Create
Create是整個(gè)構(gòu)造器的重頭戲。我們需要找到一種方法,能夠通過(guò)TObject來(lái)找到它所對(duì)應(yīng)的內(nèi)部構(gòu)造器。
我們知道,同一個(gè)類(lèi)中的靜態(tài)成員的地址對(duì)于所有類(lèi)成員來(lái)說(shuō),是一個(gè)相同的固定的地址。這樣,這個(gè)地址,就可以標(biāo)示一個(gè)特定的類(lèi)。
然后,我們知道,模板參數(shù)相同的模板類(lèi)實(shí)例類(lèi),是同一個(gè)類(lèi)。
根據(jù)這兩個(gè),我們能夠設(shè)計(jì)一種方法,通過(guò)靜態(tài)成員的地址,來(lái)找到TObject對(duì)應(yīng)的內(nèi)部構(gòu)造器的方法。下面就是這種方法的代碼。
首先,修改xBaseCreator的接口,提供一個(gè)獲取類(lèi)的Code的接口,這個(gè)Code就是模板類(lèi)中的一個(gè)靜態(tài)變量的地址。



























最后,我們把Create寫(xiě)好。











到現(xiàn)在為止,這個(gè)通用構(gòu)造器就基本完成了。代碼比較糙,只是用來(lái)說(shuō)明這個(gè)方法。至于刪除之類(lèi)的代碼,就比較簡(jiǎn)單了.
下面是完整的這個(gè)構(gòu)造器的代碼,以及測(cè)試代碼。







































































































