使用模板有什么缺点?如何避免?
http://www.cnblogs.com/royenhome/archive/2010/11/19/1881535.html
文章來(lái)源:http://group.gimoo.net/review/82612??
??templates(模板)是節(jié)省時(shí)間和避免代碼重復(fù)的極好方法,我們可以只輸入一個(gè)類(lèi)模板,就能讓編譯器實(shí)例化所需要的很多個(gè)特定類(lèi)及函數(shù)。類(lèi)模板的成員函數(shù)只有被使用時(shí)才會(huì)被實(shí)例化,下面就是work被實(shí)例化了4次,所以只有在每一個(gè)函數(shù)都在實(shí)際中被使用時(shí),我們才會(huì)得到這些函數(shù)。?
確實(shí)這是一個(gè)很重要的技術(shù),但是如果不小心,使用模板可能會(huì)導(dǎo)致代碼膨脹。什么是代碼膨脹?請(qǐng)看下面的例子:?1 ? ? ?template <class T, int num>?
2? ? ? class A?
3? ? ? {?
4? ? ? public:?
5? ? ? ? ? ? ? ? void work()?
6? ? ? ? ? ? ? ? {?static int i = 0;
7? ? ? ? ? ? ? ? ? ? ? ? cout < < "work() " < <i++<< endl;?8? ? ? ? ? ? ? ? ? ? ? ? cout < < num < < endl;?
9? ? ? ? ? ? ? ? }?
10? ? };?
11?
12? ? int main()?
13? ? {?
14? ? ? ? ? ? ? A <int, 1>v1;?
15? ? ? ? ? ? ? A <int, 2>v2;?
16? ? ? ? ? ? ? A <int, 3>v3;?
17? ? ? ? ? ? ? A <int, 4>v4;?
18? ? ? ? ? ? ? v1.work();?
19? ? ? ? ? ? ? v2.work();?
20? ? ? ? ? ? ? v3.work();?
21? ? ? ? ? ? ? v4.work();?
22? ? ? ? ? ? ? return 0;?
23? ? }?
類(lèi)模板A取得一個(gè)類(lèi)型參數(shù)T,并且它還有一個(gè)類(lèi)型為int的參數(shù),一個(gè)非類(lèi)型參數(shù)(non-type parameter),與類(lèi)型參數(shù)相比,雖然非類(lèi)型參數(shù)不是很通用,但他們是完全合法的。在本例中,由于num的不同,代碼14到17行的調(diào)用將會(huì)生成了三個(gè)A的實(shí)例,然后在18~21行又生成了不同的函數(shù)調(diào)用。?
雖然這些函數(shù)做了相同的事情(打印一個(gè)“work()”和num),但他們卻有不同的二進(jìn)制代碼。這就是所說(shuō)的由于模板導(dǎo)致的代碼膨脹。也就是說(shuō),雖然源代碼看上去緊湊而整潔,但是目標(biāo)代碼卻臃腫而松散,會(huì)嚴(yán)重影響程序的運(yùn)行效率。?
如何避免由于這種代碼膨脹呢?有一個(gè)原則,就是把C++模板中與參數(shù)無(wú)關(guān)的代碼分離出來(lái)。也就是讓與參數(shù)無(wú)關(guān)的代碼只有一份拷貝。對(duì)類(lèi)模板A可以進(jìn)行如下地修改:?
(模版類(lèi)的出現(xiàn),就是代替了人工拷貝的過(guò)程,但是在編譯期間由編譯器進(jìn)行拷貝。在上面的例子中,編譯器首先生成4個(gè)類(lèi),然后再產(chǎn)生對(duì)應(yīng)的對(duì)象。很明顯,work函數(shù)的功能一致,卻被拷貝了四次。在下面的實(shí)現(xiàn)中,可以想象,也是有4個(gè)類(lèi)A <int, 1>,A <int, 2>,A <int, 3>,A <int, 4>,但是這四個(gè)類(lèi)都繼承一個(gè)base<int>,其中派生類(lèi)的work函數(shù)還是會(huì)生成4份,但是都調(diào)用了base<int>中的work函數(shù),但是base<int>中的work函數(shù)只有一份)
1 ? ? ?template <class T>?2? ? ? class Base?
3? ? ? {?
4? ? ? public:?
5? ? ? ? ? ? ? ? void work(int num)?
6? ? ? ? ? ? ? ? {?
7? ? ? ? ? ? ? ? ? ? ? ? cout < < "work ";?
8? ? ? ? ? ? ? ? ? ? ? ? cout < < num < < endl;?
9? ? ? ? ? ? ? ? }?
10? ? };?
11?
12 ? ?template <class T, int num>?
13? ? class Derived : public Base <T>?
14? ? {?
15? ? public:?
16? ? ? ? ? ? ? void work()?
17? ? ? ? ? ? ? {?
18? ? ? ? ? ? ? ? ? ? ? Base <T>::work(num);?
19? ? ? ? ? ? ? }?
20? ? };?
21?
22? ? int main()?
23? ? {?
24? ? ? ? ? ? ? Derived <int, 1>d1;?
25? ? ? ? ? ? ? Derived <int, 2>d2;?
26? ? ? ? ? ? ? Derived <int, 3>d3;?
27? ? ? ? ? ??
28? ? ? ? ? ? ? d1.work();?
29? ? ? ? ? ? ? d2.work();?
30? ? ? ? ? ? ? d3.work();?
31? ? ? ? ? ? ? return 0;?
32? ? }?
?? ?程序中work的參數(shù)版本是在一個(gè)Base類(lèi)(基類(lèi))中的。與Derived類(lèi)一樣,Base類(lèi)也是一個(gè)類(lèi)模板,但是與Derived類(lèi)不一樣的是,它參數(shù)化的僅僅是類(lèi)型T,而沒(méi)有num。因此,所有持有一個(gè)給定類(lèi)型的Derived將共享一個(gè)單一的Base類(lèi)。比如代碼24~26行實(shí)例化的模板類(lèi)都共享Base <int>模板類(lèi),從而他們的成員函數(shù)都共享Base <int>模板類(lèi)中的work這個(gè)單一的拷貝。
?? ?模板的缺點(diǎn):不當(dāng)?shù)厥褂媚0鍟?huì)導(dǎo)致代碼膨脹,即二進(jìn)制代碼臃腫而松散,會(huì)嚴(yán)重影響程序的運(yùn)行效率。?
?? ?解決方法:把C++模板中與參數(shù)無(wú)關(guān)的代碼分離出來(lái)。 ?
總結(jié)
以上是生活随笔為你收集整理的使用模板有什么缺点?如何避免?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: TWITTER背后的开源技术
- 下一篇: python版本的服务器