重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这期内容当中小编将会给大家带来有关如何用函数模板实现和优化抽象操作,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
创新互联成立与2013年,是专业互联网技术服务公司,拥有项目成都网站制作、成都做网站、外贸营销网站建设网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元娄星做网站,已为上家服务,为娄星各地企业和个人服务,联系电话:028-86922220
在创建完成抽象操作的函数时,如:拷贝,反转和排序,你必须定义多个版本以便能处理每一种数据类型。以 max() 函数为例,
返回两个参数中的较大者:
double max(double first, double second); complex max(complex first, complex second); date max(date first, date second); //..该函数的其它版本
尽管这个函数针对不同的数据类型其实现都是一样的,但程序员必须为每一种数据类型定义一个单独的版本:
double max(double first, double second) { return first>second? first : second; } complex max(complex first, complex second) { return first>second? first : second; } date max(date first, date second) { return first>second? first : second; }
这样不但重复劳动,容易出错,而且还带来很大的维护和调试工作量。更糟的是,即使你在程序中不使用某个版本,其代码仍然增加可执行文件的大小,大多数编译器将不会从可执行文件中删除未引用的函数。
用普通函数来实现抽象操作会迫使你定义多个函数实例,从而招致不小的维护工作和调试开销。解决办法是使用函数模板代替普通函数。
使用函数模板
函数模板解决了上述所有的问题。类型无关并且只在需要时自动实例化。本文下面将展示如何定义函数模板以便抽象通用操作,示范其使用方法并讨论优化技术。
第一步:定义
函数模板的声明是在关键字 template 后跟随一个或多个模板在尖括弧内的参数和原型。与普通函数相对,它通常是在一个转换单元里声明,而在另一个单元中定义,你可以在某个头文件中定义模板。例如:
// file max.h #ifndef MAX_INCLUDED #define MAX_INCLUDED templateT max(T t1, T t2) { return (t1 > t2) ? t1 : t2; } #endif
int n=10,m=16; int highest = max(n,m); // 产生 int 版本 std::complexc1, c2; //.. 给 c1,c2 赋值 std::complex higher=max(c1,c2); // complex 版本
第二步:改进设计
上述的 max() 的实现还有些土气——参数t1和t2是用值来传递的。对于像 int,float 这样的内建数据类型来说不是什么问题。但是,对于像std::complex 和 std::sting这样的用户定义的数据类型来说,通过引用来传递参数会更有效。此外,因为 max() 会认为其参数是不会被改变的,我们应该将 t1和t2声明为 const (常量)。下面是 max() 的改进版本:
templateT max(const T& t1, const T& t2) { return (t1 > t2) ? t1 : t2; }
额外的性能问题
很幸运,标准模板库或 STL 已经在
unsigned int htonl (unsigned int hostlong); unsigned short htons (unsigned short hostshort); unsigned int ntohl (unsigned int netlong); unsigned short ntohs (unsigned short netshort);
这些函数实现相同的操作:反转多字节值的字节。其唯一的差别是方向性以及参数的大小。非常适合模板化。使用一个模板函数来替代这四个函数,我们可以定义一个聪明的模板,它会处理所有这四种情况以及更多种情形:
templateT byte_reverse(T val);
为了确定 T 实际的类型,我们使用 sizeof 操作符。此外,我们还使用 STL 的 std::reverse 算法来反转值的字节:
templateT byte_reverse(T val) { // 将 val 作为字节流 unsigned char *p=reinterpret_cast (&val); std::reverse(p, p+sizeof(val)); return val; }
使用方法
byte_reverse() 模板处理完全适用于所有情况。而且,它还可以不必修改任何代码而灵活地应用到其它原本(例如:64 位和128位)不支持的类型:
int main() { int n=1; short k=1; __int64 j=2, i; int m=byte_reverse(n);// reverse int int z=byte_reverse(k);// reverse short k=byte_reverse(k); // un-reverse k i=byte_reverse(j); // reverse __int64 }
注:模板使用不当会影响.exe 文件的大小,也就是常见的代码浮肿问题。
上述就是小编为大家分享的如何用函数模板实现和优化抽象操作了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联行业资讯频道。