博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用模板有什么缺点?如何避免?
阅读量:4155 次
发布时间:2019-05-25

本文共 1791 字,大约阅读时间需要 5 分钟。

文章来源:  

  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++模板中与参数无关的代码分离出来。  

转载地址:http://eteti.baihongyu.com/

你可能感兴趣的文章
【Python基础9】浅谈深浅拷贝及变量赋值
查看>>
Jenkins定制一个具有筛选功能的列表视图
查看>>
【Python基础10】探索模块
查看>>
【Python】将txt文件转换为html
查看>>
[Linux]Shell脚本实现按照模块信息拆分文件内容
查看>>
idea添加gradle模块报错The project is already registered
查看>>
在C++中如何实现模板函数的外部调用
查看>>
在C++中,关键字explicit有什么作用
查看>>
C++中异常的处理方法以及使用了哪些关键字
查看>>
内存分配的形式有哪些? C++
查看>>
什么是内存泄露,如何避免内存泄露 C++
查看>>
栈和堆的空间大小 C++
查看>>
什么是缓冲区溢出 C++
查看>>
sizeof C++
查看>>
使用指针有哪些好处? C++
查看>>
引用还是指针?
查看>>
checkio-non unique elements
查看>>
checkio-medium
查看>>
checkio-house password
查看>>
checkio-moore neighbourhood
查看>>