声明一个类模板,利用它分别实现两个整数、浮点数和字符的比较,求出大数和小数

        在之前的文章中曾介绍了函数模板,对于功能相同而数据类型不同的一些函数,不必定义各个函数,可以定义一个可对任何类型变量进行操作的函数模板,在调用函数时,系统会根据实参的类型,取代函数模板中的类型参数,得到具体的函数。这样可以简化程序设计。
        对于类的声明来说,也有同样的问题,有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同,如下面声明了一个类:
        class Compare_int
        {public:
         Compare_int(int a,int b)        //定义构造函数
                {x=a;y=b;}
         int max()
                {return(x>y)?x:y;}
         int min()
                {returm(x<y)?x:y:}
         private:
                int x,y;
         };
其作用是对两个整数作比较,可以通过调用成员函数max 和min得到两个整数中的大者和小者。
        如果想对两个浮点数(float型)进行比较,需要另外声明一个类:
        class Compare_float
                {public:
                        Compare_float(float a,float b)
                                {x=a;y=b;}
                        float max()
                                {return(x>y)?x:y;}
                        float min()
                                {returm(x<y)?x:y;}
                 private:

                        float x,y;

         }

        显然这基本上是重复性的工作,应该有办法减少重复的工作。C++在发展的过程中增加了模板(template)的功能,提供了解决这类问题的途径。
        可以声明一个通用的类模板,它可以有一个或多个虚拟的类型参数,如对以上两个类可以综合写出以下的类模板:
        template<class numtype>                                    //声明一个模板,虚拟类型名为numtype
        class Compare                                                      //类模板名为Compare
                {public:
                        Compare(numtype a,numtype b)        //定义构造函数
                                {x=a;y=b;}
                        numtype max()
                                {return(x>y)?x:y:}
                        numtype min()
                                {return(x<y)?x:y:}
                  private:
                        numtype x,y;
         };
        请将此类模板和前面第1个Compare_int类进行比较,可以看到有两处不同:
        (1)声明类模板时要增加一行
        template<class类型参数名>
template的意思是"模板",是声明类模板时必须写的关键字。在template后面的尖括号内的内容为模板的参数表,关键字class表示其后面的是类型参数。在本例中numtype就是一个类型参数名。这个名字是可以任意取的,只要是合法的标识符即可。这里取numtype只是表示"数据类型"的意思而已。此时,numtype并不是一个已存在的实际类型名,它只是一个虚拟类型参数名。在以后将被一个实际的类型名取代。
        (2)原有的类型名int换成虚拟类型参数名numtype(为醒目起见,上面的numtype用黑体字印出)。在建立类对象时,如果将实际类型指定为int型,编译系统就会用int取代所有的 numtype,如果指定为float型,就用float取代所有的numtype。这样就能实现一类多用
        由于类模板包含类型参数,因此又称为参数化的类。如果说类是对象的抽象,对象是类的实例。则类模板是类的抽象,类是类模板的实例。利用类模板可以建立含各种数据类型的类。
        读者最关心的一个问题是:在声明了一个类模板后,怎样使用它?怎样使它变成一个实际的类?
        先回顾一下用类来定义对象的方法:
        Compare_int cmp1(4,7);        //Compare_int是已声明的类
其作用是建立一个Compare_int类的对象,并将实参4和7分别赋给形参a和b,作为进行比较的两个整数。

        用类模板定义对象的方法与此相似,但是不能直接写成
        Compare cmp(4,7);        //Compare是类模板名
Compare是类模板名,而不是一个具体的类,类模板体中的类型numtype并不是一个实际的类型,只是一个虚拟的类型,无法用它去定义对象。必须用实际类型名取代虚拟的类型,具体的做法是:
        Compare <int>cmp(4,7);
即在类模板名之后在尖括号内指定实际的类型名,在进行编译时,编译系统就用int取代类模板中的类型参数numtype,这样就把类模板具体化,或者说实例化了。它相当于最早绍的Compareint类了。
        其一般形式为
        类模板名<实际类型名>对象名(参数表);

编写程序:

运行结果:

        有了以上介绍的基础,读者是不难看懂这个程序的。
        还有一个问题要说明:上面列出的类模板中的成员函数是在类模板内定义的。如果改为在类模板外定义,不能用一般定义类成员函数的形式:
        numtype Compare::max() {...}        //不能这样定义类模板中的成员函数
而应当写成类模板的形式:
        template<class numtype>
        numtype Compare<numtype>::max()
                {return(x>y)?x:y;}

上面第1行表示是类模板,第2行左端的 numtype 是虚拟类型名,后面的Compare <numtype>是一个整体,是带参的类。表示所定义的max 函数是在类 Compare <numtype>的作用域内的。在定义对象时,用户当然要指定实际的类型(如int),进行编译时就会将类模板中的虚拟类型名numtype全部用实际的类型代替。这样Compare <numtype>就相当于一个实际的类。
        归纳以上的介绍,可以这样声明和使用类模板:
        (1)先写出一个实际的类(如本节开头的Compare_int)。由于其语义明确,含义清楚,一般不会出错。
        (2)将此类中准备改变的类型名(如int要改变为float或char)改用一个自己指定的虚拟类型名(如上例中的numtype)。
        (3)在类声明前面加入一行,格式为
        template<class虚拟类型参数>

        template<class numtype>        //注意本行末尾无分号
        class Compare
        {...}                                            //类体
        (4)用类模板定义对象时用以下形式:
        类模板名<实际类型名>对象名;
        类模板名<实际类型名>对象名(实参表);

如:

        Compare<int>cmp;
        Compare<int>cmp(3,7);
        (5)如果在类模板外定义成员函数,应写成类模板形式:
        template<class 虚拟类型参数>
        函数类型 类模板名<虚拟类型参数>::成员函数名(函数形参表){...}

说明:
        (1)类模板的类型参数可以有一个或多个,每个类型前面都必须加 class,如
        template<class T1,class T2>
        class someclass
        {...};
        在定义对象时分别代入实际的类型名,如
        someclass<int,double> obj;
        (2)和使用类一样,使用类模板时要注意其作用域,只能在其有效作用域内用它定义对象。如果类模板是在A文件开头定义的,则A文件范围内为有效作用域,可以在其中的任何地方使用类模板,但不能在B文件中用类模板定义对象。
        (3)模板可以有层次,一个类模板可以作为基类,派生出派生模板类。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/783103.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

应用层协议原理——因特网提供的运输服务

我们已经考虑了计算机网络能够一般性地提供的运输服务。现在我们要更为具体地考察由因特网提供的运输服务类型。因特网(更一般的是TCP/IP网络)为应用程序提供两个运输层协议&#xff0c;即UDP和TCP。当软件开发者为因特网创建一个新的应用时&#xff0c;首先要做出的决定是&…

游戏AI的创造思路-技术基础-决策树(2)

上一篇写了决策树的基础概念和一些简单例子&#xff0c;本篇将着重在实际案例上进行说明 目录 8. 决策树应用的实际例子 8.1. 方法和过程 8.1.1. 定义行为 8.1.2. 确定属性 8.1.3. 构建决策树 8.1.4. 实施行为 8.1.5. 实时更新 8.2. Python代码 8. 决策树应用的实际例子…

大模型网信办备案全网最详细说明【+流程+附件】

根据目前公开的国内大模型算法备案统计来看&#xff0c;首批境内深度合成服务算法备案清单&#xff0c;总共通过41家&#xff0c;14家互联网大厂和独角兽企业成功申报算法备案32个&#xff0c;6家新兴互联网公司成功申报算法备案9个&#xff0c;仅占比21.9%。 第二批境内…

Python标准库常用模块的典型用法介绍与案例

目录 1. os模块 典型用法 案例 2. sys模块 典型用法 案例 3. datetime模块 典型用法 案例 4. re模块 典型用法 案例 5. json模块 典型用法 案例 6. random模块 典型用法 案例 7. collections模块 典型用法 案例 总结 Python作为一门功能强大的编…

控件-ProgressBar

常用属性 1.android:max:进度条的最大值 2. android: progress:进度条已完成进度值 3. android: indeterminate:如果设置成true,则进度条不精确显示进度 4.style"?android:attr/progressBarStyleHorizontal"水平进度条 案例 进度条加载

探索TXE、TC、RXNE标志位在串口通信中的轮询与中断应用

浅谈一下STM32串口中断之TXE,TC,RXNE标志位 之前做一个项目&#xff0c;用到了串口中断&#xff0c;但是对TXE、TC和RXNE标志位的作用和使用方法不是很清楚&#xff0c;导致在调试过程中遇到了一些问题。通过查阅相关资料和实际操作&#xff0c;我对这三个标志位有了更深入的了…

Python酷库之旅-第三方库Pandas(010)

目录 一、用法精讲 22、pandas.read_hdf函数 22-1、语法 22-2、参数 22-3、功能 22-4、返回值 22-5、说明 22-6、用法 22-6-1、数据准备 22-6-2、代码示例 22-6-3、结果输出 23、pandas.HDFStore.put方法 23-1、语法 23-2、参数 23-3、功能 23-4、返回值 23-5…

【数据分析】Pandas_DataFrame读写详解:案例解析(第24天)

系列文章目录 一、 读写文件数据 二、df查询数据操作 三、df增加列操作 四、df删除行列操作 五、df数据去重操作 六、df数据修改操作 文章目录 系列文章目录前言一、 读写文件数据1.1 读写excel文件1.2 读写csv文件1.3 读写mysql数据库 二、df查询数据操作2.1 查询df子集基本方…

2.5 C#视觉程序开发实例1----CamManager实现模拟相机采集图片

2.5 C#视觉程序开发实例1----CamManager实现模拟相机采集图片 1 目标效果视频 CamManager 2 CamManager读取本地文件时序 3 BD_Vision_Utility添加代码 3.0 导入链接库 BD_OperatorSets.dllSystem.Windows.Forms.dllOpencvSharp 3.1 导入VisionParam中创建的文件Util_FileO…

乡村振兴指数与其30个原始变量数据(Shp/Dta/Excel格式,2000-2022年)

数据简介&#xff1a;这份数据是我国各地级市乡村振兴指数与其30各原始变量数据并对其进行地图可视化表达。城镇化是当今中国社会经济发展的必由之路。当前我国城镇化处于发展的关键时期&#xff0c;但城镇化发展的加快却是一把双刃剑&#xff0c;为何要如此形容呢?因为当前城…

【04】微服务通信组件Feign

1、项目中接口的调用方式 1.1 HttpClient HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、最新的、功能丰富的支持 Http 协议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 JDK 自带的 URLConnectio…

科研绘图系列:R语言径向柱状图(Radial Bar Chart)

介绍 径向柱状图(Radial Bar Chart),又称为雷达图或蜘蛛网图(Spider Chart),是一种在极坐标系中绘制的柱状图。这种图表的特点是将数据点沿着一个或多个从中心向外延伸的轴来展示,这些轴通常围绕着一个中心点均匀分布。 特点: 极坐标系统:数据点不是在直角坐标系中展…

AI时代还需要产品经理吗?需要什么样的?

在人工智能技术迅速发展的今天&#xff0c;我们不禁要思考&#xff0c;产品经理这个角色是否仍然重要&#xff1f;AI时代是否还需要他们&#xff1f; 很明确的说&#xff0c;需要&#xff01;为什么呢&#xff1f; 首先&#xff0c;我们必须认识到&#xff0c;AI虽然具有强大…

如何理解李彦宏说的“不要卷模型,要卷应用”

如何理解李彦宏说的“不要卷模型&#xff0c;要卷应用” “大家不要卷模型&#xff0c;要卷应用”这句话的意思是&#xff0c;呼吁行业不要把过多的精力和资源投入到模型的研发竞争中&#xff0c;而是应该更加注重基于模型的应用开发。 李彦宏提出这一观点的原因主要有以下几点…

容联云发布容犀大模型应用,重塑企业“营销服”|WAIC 2024

7月6日&#xff0c;在2024世界人工智能大会上&#xff0c;容联云成功举办主题为“数智聚合 产业向上”的生成式应用与大模型商业化实践论坛。 论坛上&#xff0c;容联云发布了容犀智能大模型应用升级&#xff0c;该系列应用包括容犀Agent Copilot、容犀Knowledge Copilot、容犀…

PHP星座微信小程序系统源码

&#x1f31f;每日星运&#xff0c;尽在掌握&#xff01;星座微信小程序&#xff0c;你的专属星空指南✨ &#x1f308; 一、每日运势&#xff0c;精准推送 想知道今天的你运势如何&#xff1f;星座微信小程序来告诉你&#xff01;&#x1f52e; 每天醒来&#xff0c;打开小程…

排座椅【详细代码题解】

[NOIP2008 普及组] 排座椅 题目描述 上课的时候总会有一些同学和前后左右的人交头接耳&#xff0c;这是令小学班主任十分头疼的一件事情。不过&#xff0c;班主任小雪发现了一些有趣的现象&#xff0c;当同学们的座次确定下来之后&#xff0c;只有有限的 D D D 对同学上课时…

(二)前端javascript中的数据结构之栈

栈是一种遵从后进先出&#xff08;LIFO&#xff09;原则的有序集合。新添加的或待删除的元素都保存在栈的 同一端&#xff0c;称作栈顶&#xff0c;另一端就叫栈底。在栈里&#xff0c;新元素都靠近栈顶&#xff0c;旧元素都接近栈底。 栈是限定仅在表的一端进行插入和删除操作…

CnosDB:深入理解时序数据修复函数

CnosDB是一个专注于时序数据处理的数据库。CnosDB针对时序数据的特点设计并实现了三个强大的数据修复函数&#xff1a; timestamp_repair – 对时间戳列进行有效修复&#xff0c;支持插入、删除、不变等操作。value_repair – 对值列进行智能修复&#xff0c;根据时间戳间隔和…

【学习笔记】网络设备(华为交换机)基础知识2——常用设备管理命令

一、前期准备 提示&#xff1a;下面所有学习内容都是基于以下条件完成的 条件1.已经可以正常访问交换机的命令行接口 Console口本地访问教程参考 ① &#xff1a;使用第三方工具&#xff08;secureCRT软件&#xff09;通过console口本地访问访问交换机的详细操作过程 Telnet访…