『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算法 的 设计 ...
随机推荐
- 原创跑酷小游戏《Cube Duck Run》 - - 方块鸭快跑
自从unity5出来才开始关注unity,业余时间尝试做了个小游戏: <方块鸭快跑> (Cube Duck Run) 像素风,3d视角,色彩明快,有无尽和关卡两种模式. 应用连接: goo ...
- java mongoDB 二级数组嵌套查询
场景: 会员集合下有多个会员文档,会员文档下有多个订单文档,订单买了多个商品文档 member->orders>orderItems 要求: 通过会员id和商品id验证会员是否购买过该商品 ...
- centos 7安装部署docker
1.centos 7 在windows下通过vm虚拟机安装centos 7: VMware-workstation-full-10.0.3-1895310 centos 7 2.要求 操作系统的内核版 ...
- ArcEngine :The XY domain on the spatial reference is not set or invalid错误
在创建数据集的时候,提示The XY domain on the spatial reference is not set or invalid错误. 原因:未设置空间参考(ISpatialRefer ...
- mvc中Url.RouteUrl或者Html.RouteLink实现灵活超链接,使href的值随路由名称或配置的改变而改变[bubuko.com]
mvc,超链接除了直接写在a标签的href内还可以使用路由规则来生成,这样在改变了路由规则或者路由名称时不用再去代码中更改href的值,而且还容易遗漏.借助Url.RouteUrl或者Html.Rou ...
- 【FTP】FTP文件上传下载-支持断点续传
Jar包:apache的commons-net包: 支持断点续传 支持进度监控(有时出不来,搞不清原因) 相关知识点 编码格式: UTF-8等; 文件类型: 包括[BINARY_FILE_TYPE(常 ...
- HDU2896 病毒侵袭
题目大意:给出若干病毒的特征码,不超过500个.每个病毒的特征码长度在20~200之间.现在有若干网站的源代码,要检测网站的源代码中是否包含病毒.网站的个数不超过1000个,每个网站的源代码长度在70 ...
- [zz] 海洋环境的光能传递
source: http://cgangs.com/article/2557?source=weibo 就我们的目的来说,海洋环境仅由四部分组成:水表.空气.阳光和水表以下部分.在本节中,我们在数学和 ...
- 最新版STS因为JDK版本太低无法启动的解决办法
-startup plugins/org.eclipse.equinox.launcher_1..jar --launcher.library plugins/org.eclipse.equinox. ...
- MVC4 +EasyUI Tabs 使用
Tabs 右键菜单功能实现 前端 <div id="tabs" class="easyui-tabs" fit="true" bord ...