您的位置: 首页 N搜咨询 文章阅读 C++中用函数模板实现和优化抽象操…
打印本页 放大字体 关闭本页
C++中用函数模板实现和优化抽象操作

作者:N搜网友 编辑:N搜网 录入:N搜网 来源:N搜网络
录入时间:2006-8-17 更新时间:2006-8-17 点击次数:722
主标题:C++中用函数模板实现和优化抽象操作
副标题:C++中用函数模板实现和优化抽象操作
短标题:C++中用函数模板实现和优化抽象操作
 
   本文介绍函数模板的概念、用途以及如何创建函数模板和函数模板的使用方法......
  在创建完成抽象操作的函数时,如:拷贝,反转和排序,你必须定义多个版本以便能处理每一种数据类型。以 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
    template <class T> T max(T t1, T t2)
    {
   return (t1 > t2) ? t1 : t2;
    }
    #endif
  <class T> 定义 T 作为模板参数,或者是占位符,当实例化 max()时,它将替代具体的数据类型。max 是函数名,t1和t2是其参数,返回值的类型为 T。你可以像使用普通的函数那样使用这个 max()。编译器按照所使用的数据类型自动产生相应的模板特化,或者说是实例:
    int n=10,m=16;
    int highest = max(n,m); // 产生 int 版本
    std::complex<double> c1, c2;
    //.. 给 c1,c2 赋值
    std::complex<double> higher=max(c1,c2); // complex 版本 
  第二步:改进设计
  上述的 max() 的实现还有些土气——参数t1和t2是用值来传递的。对于像 int,float 这样的内建数据类型来说不是什么问题。但是,对于像std::complex 和 std::sting这样的用户定义的数据类型来说,通过引用来传递参数会更有效。此外,因为 max() 会认为其参数是不会被改变的,我们应该将 t1和t2声明为 const (常量)。下面是 max() 的改进版本:
    template <class T> T max(const T& t1, const T& t2)
    {
   return (t1 > t2) ? t1 : t2;
    }
  额外的性能问题
  很幸运,标准模板库或 STL 已经在 <algorithm> 里定义了一个叫 std::max()的算法。因此,你不必重新发明。让我们考虑更加现实的例子,即字节排序。众所周知,TCP/IP 协议在传输多字节值时,要求使用 big endian 字节次序。因此,big endian 字节次序也被称为网络字节次序(network byte order)。如果目的主机使用 little endian 次序,必须将所有过来的所字节值转换成 little endian 次序。同样,在通过 TCP/IP 传输多字节值之前,主机必须将它们转换成网络字节次序。你的 socket 库声明四个函数,它们负责主机字节次序和网络字节次序之间的转换:
    unsigned int htonl (unsigned int hostlong);
    unsigned short htons (unsigned short hostshort);
    unsigned int ntohl (unsigned int netlong);
    unsigned short ntohs (unsigned short netshort); 
  这些函数实现相同的操作:反转多字节值的字节。其唯一的差别是方向性以及参数的大小。非常适合模板化。使用一个模板函数来替代这四个函数,我们可以定义一个聪明的模板,它会处理所有这四种情况以及更多种情形:
    template <class T> T byte_reverse(T val);
  为了确定 T 实际的类型,我们使用 sizeof 操作符。此外,我们还使用 STL 的 std::reverse 算法来反转值的字节:
    template <class T> T byte_reverse(T val)
    {
   // 将 val 作为字节流
   unsigned char *p=reinterpret_cast<unsigned char*> (&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 文件的大小,也就是常见的代码浮肿问题。
N搜网-中国网上商店商品服务搜索门户]:[本文章由N搜网于2006-8-17录入系统,网址:www.nsall.com

打印本页 放大字体 关闭本页
 
 
相关主题文章
C++中的const限定修饰符 C++中的虚函数(virtual function)
C++中确定基类有虚析构函数 C++中用vectors改进内存的再分配
C++中用函数模板实现和优化抽象操作 CBuilder中帮助文件的连接及显示讨论
CRC循环校验的具体算法 C标准中一些预定义的宏
C程式中关于整数储存的说明 C数值计算程序移植到VC开发环境
C语言初学者入门讲座 第八讲 转移语句 C语言初学者入门讲座 第二讲 数据类型(1)
C语言初学者入门讲座 第二讲 数据类型(2) C语言初学者入门讲座 第二讲 数据类型(3)
C语言初学者入门讲座 第九讲 数组(1) C语言初学者入门讲座 第九讲 数组(2)
C语言初学者入门讲座 第六讲 分支结构(1) C语言初学者入门讲座 第六讲 分支结构(2)
C语言初学者入门讲座 第七讲 循环结构 C语言初学者入门讲座 第三讲 基础语句
C语言初学者入门讲座 第十二讲 结构(1) C语言初学者入门讲座 第十二讲 结构(2)
C语言初学者入门讲座 第十二讲 结构(3) C语言初学者入门讲座 第十讲 函数(1)
C语言初学者入门讲座 第十讲 函数(2) C语言初学者入门讲座 第十讲 函数(3)
C语言初学者入门讲座 第十讲 函数(4) C语言初学者入门讲座 第十六讲 文件(1)
C语言初学者入门讲座 第十六讲 文件(2) C语言初学者入门讲座 第十三讲 联合
C语言初学者入门讲座 第十四讲 枚举与位运算(1) SNMP用VC++6.0实现的方法
XML在系统日志设计中的运用 利用VC++编写Windows95的CPL组件
利用VC++开发所见即所得的打印程序 利用VB自制OCX控件
利用Visual Basic 实现无线通讯 利用VC实现AVI文件的图像截取
利用VB实现宽行打印的一个技巧 调试Release版本应用程序
利用VC++编程实现程序自动启动 利用VB制作MP3播放列表
利用VC++开发ASP图像处理组件 利用VC++获取异构型数据库库结构信息
如何在ASP.Net 中把图片存入数据库 用TAPI为掌上电脑开发通讯应用程序
让窗口一直在上面 通过DELPHI小程序在WINDOWS下更好地使用DOS批处理…
用ASP实现的2000年倒记时程序 在vb组件内调用excel2000实现GIF饼图
用VB编写接近实际的抽奖程序 微软风格的Explore
在 C# 中使用画笔 用VB6分离出文本框的单词
如何拦截键盘输入 在VB5.0下有效控制鼠标的输入焦点
用VB5创建B/S程序 在ASP中用“正则表达式对象”来校验数据的合法性…
用VB实现局域网屏幕监视 用ASP实现网上考试系统
在ASP中利用“正则表达式” 对象实现UBB风格… [组图] 用Excel的宏编制个人证券账户管理器
用Powerbuilder进行分布式应用开发三级体系结构 在Asp.Net中从sqlserver检索(retrieve)图片
论游戏中的搜索问题(初级篇) 用VB调试串口通讯
使用API创建窗体(类似VC的创建过程) 用Delphi做一个OpenGL控件
如何在程序中使用自己的库单元 消息队列在VB.NET数据库开发中的应用
在VFP5.0中实现中英文自动切换 在BCB下使用GExperts的Debug功能
用FoxWeb在网上快速发布你的FOXPRO数据库 用VB6.0设计一个打字练习软件
在VFP中实现跟变式组合框及椭圆图形菜单 用Delphi合并Word表格中单元格
用BCB实现超星格式转换为BMP格式 拼图游戏的算法
在拷贝、删除文件时显示飞行的文件夹动画 在PB中如何使用Microsoft Outlook发送邮件
在PowerBuilder中调用ChooseColor函数 一个简单的MP3播放器
如何用pb实现MSACCESS数据库的图片字段存取 在C++Builder中使用Compress Html Help
压缩HTMl文件 在powerbuilder中向Excel传递数据
人民币大小写转换算法 在PB中应用灵活多样的排序
如何在程序启动默认浏览器与电子邮件系统 用C#编写获取远程IP,MAC的方法
用API实现在MSN的信息提示 真正意义上的前台窗口切换
如何在ASP程序中打印Access报表 如何在Windows应用程序中实现电子注册功能
上楼梯算法的java实现 实时曲线的绘制和保存
用Vb.net实现自定义界面 刘徽《九章算术》中的勾股数
ASCII码表 水仙花数
 
 
 
本站关键字:网上商店商品服务大全 网上购物导航 在线购物搜索引擎 网店比较购物 网络商城 特色网上超市商店 网上网络开店购物