模板是一種源碼復用技術,在某些情況下使用它可以使代碼看起來非常優雅,著名的boost庫就是模板發揚的典范.
然而模板也存在弊端,大量使用模板可能導致代碼膨脹.下面介紹一種解決的方案:
我們首先看一段一般代碼:
template
<
typename?T
>
class
?Vector

{
public
:
????
virtual
?
void
?Say()

????
{
????????
const
?type_info
&
????t?
=
?typeid(T);
????????std::cout?
<<
?
"
Vector<
"
?
<<
?t.name()?
<<
?
"
>::Hello
"
?
<<
?std::endl;
????}
}
;

//
?特例化
template
<>
class
??Vector
<
void
*>
{
public
:
????
virtual
?
void
?Say()

????
{
????????std::cout?
<<
?
"
Vector<void*>::Hello
"
?
<<
?std::endl;
????}
}
;

int
?_tmain(
int
?argc,?_TCHAR
*
?argv[])

{
????Vector
<
int
*>
????pIntVec;
????pIntVec.Say();
????Vector
<
double
*>
????pDoubleVec;
????pDoubleVec.Say();
????
return
?
0
;
}
輸出:
Vector<int *>::Hello
Vector<double *>::Hello
從這里,我們可以看出程序在運行的過程中生產了兩分Vector的代碼(int*和double*),盡管這里有特例化,然而類型不匹配,編譯器在編譯過程中無法定位到特例化版本.如果這個Vector被濫用的化,我想即使是一個中等規模的程序也可能耗費成兆字節的代碼控件.
我們必須尋找一種中間橋梁使編譯器在編譯過程中定位到void*的特例化版本.按照模板選擇策略,編譯器總是選擇最特例化的模板,我們可以通過一個中間的模板聯系起上面兩個版本的模板.下面看一段代碼:
template
<
typename?T
>
class
?Vector

{
public
:
????
virtual
?
void
?Say()

????
{
????????std::cout?
<<
?
"
Vector::Hello
"
?
<<
?std::endl;
????}
}
;

//
?特例化
template
<>
class
??Vector
<
void
*>
{
public
:
????
virtual
?
void
?Say()

????
{
????????std::cout?
<<
?
"
Vector<void*>::Hello
"
?
<<
?std::endl;
????}
}
;

//
?特例化
template
<
typename?T
>
class
?Vector
<
T
*>
?:?
public
?Vector
<
void
*>
{
}
;

int
?_tmain(
int
?argc,?_TCHAR
*
?argv[])

{
????Vector
<
int
*>
????pIntVec;
????pIntVec.Say();
????Vector
<
double
*>
????pDoubleVec;
????pDoubleVec.Say();
????
return
?
0
;
}
輸出:
Vector<void*>::Hello
Vector<void*>::Hello
從這里,我們可以看出程序在運行過程中全部使用Vector<void*>的版本.class Vector<T*>模板便是關鍵的環節.編譯器在編譯過程中,由于class Vector<T*>比class Vector更特例化,所以遇到Vector<int*>和Vector<double*>時都選擇class Vector<T*>,而class Vector<T*>繼承Vector<void*>,一個更加特例化版本,所以編譯器不再產生新的模板而采用Vector<void*>這個最特例化版本,這樣所有指針模板都歸結到Vector<void*>,而class Vector<T*>為用戶提供了一個精美而且安全的界面,而Vector<void*>作為底層實現細節被隱藏.
以上代碼在VC 7.1(VS2003)中編譯通過,由于VC6對模板支持不好,所以模板的高級用法一般不要在VC6中使用.
下載演示代碼
posted on 2006-03-27 18:54
萬連文 閱讀(2339)
評論(7) 編輯 收藏 引用 所屬分類:
模板