使用模板有什么缺点?如何避免?
http://www.cnblogs.com/royenhome/archive/2010/11/19/1881535.html
文章來源:http://group.gimoo.net/review/82612??
??templates(模板)是節省時間和避免代碼重復的極好方法,我們可以只輸入一個類模板,就能讓編譯器實例化所需要的很多個特定類及函數。類模板的成員函數只有被使用時才會被實例化,下面就是work被實例化了4次,所以只有在每一個函數都在實際中被使用時,我們才會得到這些函數。?
確實這是一個很重要的技術,但是如果不小心,使用模板可能會導致代碼膨脹。什么是代碼膨脹?請看下面的例子:?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? ? }?
類模板A取得一個類型參數T,并且它還有一個類型為int的參數,一個非類型參數(non-type parameter),與類型參數相比,雖然非類型參數不是很通用,但他們是完全合法的。在本例中,由于num的不同,代碼14到17行的調用將會生成了三個A的實例,然后在18~21行又生成了不同的函數調用。?
雖然這些函數做了相同的事情(打印一個“work()”和num),但他們卻有不同的二進制代碼。這就是所說的由于模板導致的代碼膨脹。也就是說,雖然源代碼看上去緊湊而整潔,但是目標代碼卻臃腫而松散,會嚴重影響程序的運行效率。?
如何避免由于這種代碼膨脹呢?有一個原則,就是把C++模板中與參數無關的代碼分離出來。也就是讓與參數無關的代碼只有一份拷貝。對類模板A可以進行如下地修改:?
(模版類的出現,就是代替了人工拷貝的過程,但是在編譯期間由編譯器進行拷貝。在上面的例子中,編譯器首先生成4個類,然后再產生對應的對象。很明顯,work函數的功能一致,卻被拷貝了四次。在下面的實現中,可以想象,也是有4個類A <int, 1>,A <int, 2>,A <int, 3>,A <int, 4>,但是這四個類都繼承一個base<int>,其中派生類的work函數還是會生成4份,但是都調用了base<int>中的work函數,但是base<int>中的work函數只有一份)
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的參數版本是在一個Base類(基類)中的。與Derived類一樣,Base類也是一個類模板,但是與Derived類不一樣的是,它參數化的僅僅是類型T,而沒有num。因此,所有持有一個給定類型的Derived將共享一個單一的Base類。比如代碼24~26行實例化的模板類都共享Base <int>模板類,從而他們的成員函數都共享Base <int>模板類中的work這個單一的拷貝。
?? ?模板的缺點:不當地使用模板會導致代碼膨脹,即二進制代碼臃腫而松散,會嚴重影響程序的運行效率。?
?? ?解決方法:把C++模板中與參數無關的代碼分離出來。 ?
總結
以上是生活随笔為你收集整理的使用模板有什么缺点?如何避免?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TWITTER背后的开源技术
- 下一篇: 后台开发需要的技能