『c++』 模板(template)--- 参数化多态性
---恢复内容开始---
题外话:
模板机制的设计和细节是由Bjarne Stroustrup在其1988年10月发表的名为“Parameterized Types for C++”一文中披露的。
引入:
假设有两个类
它们的结构完全相同,差别就是数据类型int与double,因此我们可以引入下图结构表示:
在建立对象时用实参int或double代入形参T即可,这种做法成为参数化,即是将数据类型作为参数传递,用以替代形参T的实参可以是预定义数据类型或用户自定义数据类型(主要是类的对象),这是参数化的多态性。
详解:
一 函数模板
上图定义了函数模板,主函数建立了三个模板函数,其中sq(i)使用 int 类型将类型形参 T实例化,sq(l)使用 long 型使形参T实例化,sq(5.55)则是double型。
由此可见,在函数模板中使用类型参数 T 作为形参,这不是具体函数而是函数的抽象。等到进行实例化,即代入具体类型实参例如int、double等以后,就建立了具体函数,被称为模板函数。
二,函数模板的重载
由结果明显可以看出,max(i,j),max(d,f),max(ch,hc)重载的为模板函数,max(d,j),max(i,d),max(ch,f)则调用的重载函数,注意下max(i,j),i,j同为int类型,max(d,f),d,f同为double型,ch,hc则同为char,我们返回查看函数并未发现与之相匹的重载函数,而max(d,j),max(i,d),我们在找到了与其匹配的重载函数,其恰巧也是调用的相应重载函数,但对于max(ch,f),ch为char类型,f为double的类型,首先程序中没有与之匹配的重载函数,也无匹配的函数模板,肿么办?程序显示了其调用了void max(int a, double b),我们不禁疑惑,为什么它不调用void max(double b, int a),而偏偏调用前一个函数,细观察另个函数的形式参数,不难发现void max(int a, double b),第二个形式参数为double类型,与f为同一类型,相比void max(double b, int a)更为接近,为什么会这样呢?查看调用的规则,我们会发现在混合使用重载的函数和模板时,应当避免二义性。此时它们的调用顺序是:
1.先调用匹配的重载函数
2. 如无匹配的重载函数,则调用匹配的函数模板。如果找到,则将其实例化,建立一个模板函数
3. 如再匹配不上,则调用相近的重载函数,此时可能丢失精度。
因此,可粗略地归纳为:先重载,再模板,后相近。
三 重载函数与函数模板都属于多态性机制,它们的区别如下:
(1)主函数调用重载函数和模板函数的格式完全相同。
重载函数的优点是能够对不同数据类型使用不同程序逻辑进行类似操作。例如用于求取int或double的最大值的程序逻辑和操作就和求取char或char*的最大值的程序逻辑和操作差别很大。而函数模板无法处理。
如果每种数据类型的程序逻辑和操作相同,则使用函数模板将会更加简洁和方便。
模板是一种代码产生机制。
(2)对于重载函数,无论它们使用与否,全部都存于代码区中,都占用空间。
而对于函数模板,只当使用一个具体参数类型时才建立一个模板函数,而当使用另一个具体参数类型时再建立另一个模板函数。编程方便,使用灵活,效率较高。
---恢复内容结束---
『c++』 模板(template)--- 参数化多态性的更多相关文章
- 『WPF』DataGrid的使用
原文 『WPF』DataGrid的使用 几点说明 这里主要是参考了MSDN中关于DataGrid的说明 这里只会简单说明在WPF中,DataGird最简单的使用方法 对于MSDN中的翻译不会很详细,也 ...
- 『片段』OracleHelper (支持 多条SQL语句)
C# 调用 Oracle 是如此尴尬 >System.Data.OracleClient.dll —— .Net 自带的 已经 过时作废. >要链接 Oracle 服务器,必须在 本机安装 ...
- 『实践』VirtualBox 5.1.18+Centos 6.8+hadoop 2.7.3搭建hadoop完全分布式集群及基于HDFS的网盘实现
『实践』VirtualBox 5.1.18+Centos 6.8+hadoop 2.7.3搭建hadoop完全分布式集群及基于HDFS的网盘实现 1.基本设定和软件版本 主机名 ip 对应角色 mas ...
- 『AngularJS』$location 服务
项目中关于 $location的用法 简介 $location服务解析在浏览器地址栏中的URL(基于window.location)并且让URL在你的应用中可用.改变在地址栏中的URL会作用到$loc ...
- [原创] 【2014.12.02更新网盘链接】基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装
[原创] [2014.12.02更新网盘链接]基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装 joinlidong 发表于 2014-11-29 14:25:50 ...
- JS 中通过对象关联实现『继承』
JS 中继承其实是种委托,而不是传统面向对象中的复制父类到子类,只是通过原型链将要做的事委托给父类. 下面介绍通过对象关联来实现『继承』的方法: Foo = { // 需要提供一个 init 方法来初 ...
- 『摄影欣赏』16幅 Romantic 风格照片欣赏【组图】
今天,我们将继续分享人类情感的系列文章.爱是人类最重要的感觉,也可能是各种形式的艺术(电影,音乐,书,画等)最常表达的主题 .这里有40个最美丽的爱的照片,将激励和给你一个全新的视觉角度为这种情绪.我 ...
- 『开源』Slithice 2013 服务器集群 设计和源码
相关介绍文章: <『设计』Slithice 分布式架构设计-支持一体式开发,分布式发布> <『集群』001 Slithice 服务器集群 概述> <『集群』002 Sli ...
- 『设计』Laura.Compute 设计思路
前言: 前一篇文章 <『开源』也顺手写一个 科学计算器:重磅开源> ,继 Laura.Compute 算法开源之后,有 博客园 园友 希望公开一下 Laura.Compute算法 的 设计 ...
随机推荐
- unity, 按类型查找文件
- 免装版tomcat注册成windows系统服务方法
如果一台服务器要部署两个应用,而且又各自不受影响的话,只能使用两个端口两个tomcat分别管理 在这里吐槽一下tomcat,为毛停止服务就把所有应用都停了,更新其中一个,就要把所有的都停了,然后更新完 ...
- [综]隐马尔可夫模型Hidden Markov Model (HMM)
http://www.zhihu.com/question/20962240 Yang Eninala杜克大学 生物化学博士 线性代数 收录于 编辑推荐 •2216 人赞同 ×××××11月22日已更 ...
- USVN
我们最近将快盘上的东西迁移到了svn上,因为快盘总是不会不小心删掉或者修改了某些文件.为了能保留历史记录我们统一迁移到svn上.为了方便权限管理,我对比了几个svn的权限管理工具,最后觉得还是usvn ...
- PHP手机,邮箱正则匹配
/*此处用于验证手机*/ $phone_preg = '/^1[3|4|5|7|8]\d{9}$/'; $email_preg = '/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+) ...
- Socket与Http方式解析发送xml消息封装中间件jar包
最近项目代码中太多重复的编写Document,不同的接口需要不同的模板,于是重写提取公共部分打成jar包,方便各个系统统一使用~ 提取结构: Http连接方式: import java.nio.cha ...
- Codeforces Round #383 (Div. 2) D. Arpa's weak amphitheater and Mehrdad's valuable Hoses(分组背包+dsu)
D. Arpa's weak amphitheater and Mehrdad's valuable Hoses Problem Description: Mehrdad wants to invit ...
- osgi笔记
Bundle-Classpath可以实现内嵌jar. 一个Bundle的Activator不需要进行Export 一个Package中的类被两个ClassLoader加载,包中的Private cla ...
- [ActionScript 3.0] 图片左右循环移动
有时候多张图片展示需求中,需要左右循环移动展示,为了以后省时间思考,写个例子: import com.tweener.transitions.Tweener; import flash.display ...
- Solaris 自动挂载
修改文件:vim /etc/vfstab添加命令:/dev/dsk/c2t0d0p0:1 - /media/PARTITION1 pcfs ...