C++泛型基础

2023-11-01

1.泛型的基本思想

泛型编程(Generic Programming)是一种语言机制,通过它可以实现一个标准的容器库。像类一样,泛型也是一种抽象数据类型,但是泛型不属于面向对象,它是面向对象的补充和发展。
在面向对象编程中,当算法与数据类型有关时,面向对象在对算法的抽象描述方面存在一些缺陷。
比如对栈的描述:
class stack
{

   push(参数类型)  //入栈算法

   pop(参数类型)   //出栈算法

}
如果把上面的伪代码看作算法描述,没问题,因为算法与参数类型无关。但是如果把它写成可编译的源代码,就必须指明是什么类型,否则是无法通过编译的。使用重载来解决这个问题,即对N种不同的参数类型写N个push和pop算法,这样是很麻烦的,代码也无法通用。
若对上面的描述进行改造如下:
首先指定一种通用类型T,不具体指明是哪一种类型。
class stack<参数模板 T>
{

   push(T)  //入栈算法

   pop(T)   //出栈算法

}

这里的参数模板T相当于一个占位符,当我们实例化类stack时,T会被具体的数据类型替换掉。
若定义对象S为statc类型,在实例化S时若我们将T指定int型则:
这时候类S就成为:
class S
{
    push(int)  //入栈算法
    pop(int)   //出栈算法
}
这时我可以称class stack<参数模板 T>是类的类,通过它可以生成具体参数类型不同的类。


2.泛型在C++中的应用

泛型在C++中的主要实现为模板函数和模板类。
通常使用普通的函数实现一个与数据类型有关的算法是很繁琐的,比如两个数的加法,要考虑很多类型:
int add(int a,int b) { return a+b; }
float add(float a,float b) { return  a+b; }
。。。。
虽然在C++中可以通过函数重载来解决这个问题,但是反复写相同算法的函数是比较辛苦的,更重要的是函数重载是静态编译,运行时占用过多内存。
在此我们可以用C++的模板函数来表达通用型的函数,如下:
template<typename T> // 模板声明
T add(T a,T b) { return a+b; }  // 注意形参和返回值的类型
这时C++编译器会根据add函数的参数类型来生成一个与之对应的带具体参数类型的函数并调用。
例如:
#include <iostream>
using namespace std;
template <typename T>
T add(T a,T b)  //注意形参和返回类型
{   
 return a+b;

void main()
{
    int num1, num2, sum; 
    cin>>num1>>num2;
    sum=add(num1,num2); //用int匹配模版参数T,若sum,num1,num2类型不一致则无法匹配。
    cout<<sum;
}


3.函数模板的性质

1) 函数模板并不是真正的函数,它只是C++编译生成具体函数的一个模子。
2) 函数模板本身并不生成函数,实际生成的函数是替换函数模板的那个函数,比如上例中的add(sum1,sum2),
    这种替换是编译期就绑定的。
3) 函数模板不是只编译一份满足多重需要,而是为每一种替换它的函数编译一份。
4) 函数模板不允许自动类型转换。
5) 函数模板不可以设置默认模板实参。比如template <typename T=0>不可以。


4.C++模版函数的语法

template  <typename 模版参数列表…>
函数返回类型 函数名(形参列表…)
上面两行可以合并成一行。
例如:
下面的几种写法是等效的并且class 和typename是可以互换的。
template  <typename T1, typename T2>
T1 fun(T1, T2, int )
{  //…..}
template  <typename T1,T2>  T1 fun(T1, T2, int )
{  //…..}
template  <class T1, class T2>
 T1 fun(T1, T2, int )
{  //…..}
template  <class T1,T2>  T1 fun(T1, T2, int )
{  //…..}


5.C++模版类的语法

template  <class 模版参数列表…>
class 类名
{ //类体}
成员的实现…
例如:
//类声明部分,有两个模板参数T1,T2
template  <class T1, class T2 >  
class A {
   private:
   int a;
  T1 b;  //成员变量也可以用模板参数
  public: 
  int fun1(T1 x, int y );
 T2 fun2(T1 x, T2 y);
}
//类实现部分
template  <class T1, class T2 >
int A<T1>:: fun1(T1 x, int y ){//实现…… }
 template  <class T1, class T2 >
T2 A<T1,T2>:: fun2(T1 x, T2 y) {//实现…… }
 //使用类A
 int main( ) {
 //定义对象a,并用int替换T1, float替换T2
   A<int, float>  a;
   //实例化a,调用a的属性和方法……
}
由上例可以看出, 类模板参数T1,T2对类的成员变量和成员函数均有效。
在C++编程中,当你要实现的一个类的某些成员函数和成员变量的算法跟数据类型有关,可以考虑用类模板,且C++版的数据结构算法大都用类模板实现。


6.类模板的性质

1) 类模板不是真正的类,它只是C++编译器生成具体类的一个模子。
2) 类模板可以设置默认模板实参。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++泛型基础 的相关文章

随机推荐

  • 前端自动埋点

    起源是在测试时候没有报错 系统功能不正常 和测试查找错误很麻烦 埋点就是在某个功能函数里上报一些信息 比较类试express的中间件机制 但是没有操作的权限 自定义express的打印日志中间件 app get req res gt con
  • uniapp关闭顶部导航栏

    在page json中输入以下代码 navigationStyle custom app plus titleNView false
  • 微信小程序+uni-app知识点总结

    微信小程序知识点合集 1 小程序的优势和劣势有哪些 优势 1 容易推广 在微信中 小程序拥有众多入口 例如附近的小程序 小程序码 分享 发现 小程序等五十多个的入口 这些都有助于推广小程序 2 使用便捷 用户在使用小程序时 只需要轻轻点一下
  • Varnish的简单配置及使用

    一 Varnish的简单介绍 1 varnish是什么 Varnish是一个web加速器 被安装在web应用程序前面 缓存web应用程序 并响应用户请求 是一款具有高性能的开源HTTP加速器 具有方向代理及缓存的功能 功能与squid服务器
  • 基于STM32emWin5.32的移植

    基于STM32emWin532版本的移植 移植前提 1 下载所需源码 2 直接拷贝Cubemx的STemwin 文件说明 2 需已完成底层绘制LCD的驱动调试 移植 在项目工程目录增加以下文件夹及文件 配置单次图像刷写最大允许字节 配置驱动
  • 【ARIMA-WOA-LSTM】差分自回归移动平均方法-鲸鱼优化算法-LSTM预测研究(python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Python代码实现 1 概述 差分自回归移动平均模型 ARIMA 是一种
  • 加速读取——三式(getchar,std::ios::sync_with_stdio(false)、cin.tie(0))

    在一些题目中会出现数据输入很大的情况 如果我们运用不好读取数据工具的话 那么很可能会在读取数据上花费较多的时间 甚至还没读完就超时了 读取速度 cin lt cin 关闭流同步 lt scanf lt getchar cin 关闭流同步 为
  • mysql让自增的id重新从0开始的命令

    1 清空表 2 TRUNCATE TABLE 表名
  • Linux下的压缩zip,解压缩unzip命令详解及实例

    http www cnblogs com zdz8207 p 3765604 html
  • Python爬虫分布式架构 - Redis/RabbitMQ工作流程介绍

    在大规模数据采集和处理任务中 使用分布式架构可以提高效率和可扩展性 本文将介绍Python爬虫分布式架构中常用的消息队列工具Redis和RabbitMQ的工作流程 帮助你理解分布式爬虫的原理和应用 为什么需要分布式架构 在数据采集任务中 单
  • 列举工作中常用的几个git命令?

    列举工作中常用的几个git命令 新增文件的命令 git add file或者git add 提交文件的命令 git commit m或者git commit a 查看工作区状况 git status s 拉取合并远程分支的操作 git fe
  • React16入门

    环境搭建 安装node 安装官方脚手架create react app npm install g create react app 创建项目 进入文件夹 进入cmd运行命令 mkdir ReactDemo 创建ReactDemo文件夹 c
  • 固态硬盘和机械硬盘的区别

    固态硬盘的应用范围要比机械硬盘的使用范围更广泛 固态硬盘在电子世界中起着非常重要的部件 而机械硬盘使用范围就不像固态硬盘那样灵活了 目前固态硬盘中最大的容量体积为1 6TB 传言IBM公司开始测试4TB的高速固态硬盘组了 和机械硬盘相比按T
  • jmeter配置java版本,Jmeter 在windows下的安装配置方法

    Jmeter通常用于并发测试 本文介绍Jmeter工具的安装步骤 2 安装jdk 下载完成后 双击安装 2 步骤二 配置jdk环境变量 右键计算机属性 gt 高级系统设置 gt 系统属性 gt 高级 gt 环境变量 gt 添加如下的系统变量
  • 2021-12-5 《聪明的投资者》学习笔记

    摘自 聪明的投资者 The Intelligent Investor 第4版 本杰明 格雷厄姆 第一章 投资与投机 聪明投资者的预期收益 第二章 投资者与通货膨胀 第三章 一个世纪的股市历史 1972年年初的股价水平 股市周期性 股价 利润
  • 【千律】C++基础:获取数组中的最大值和最小值

    include
  • springboot中的json、gson、fastjson如何使用与日期格式转换

    关于如何引用json gson fastjson srpngboot中默认用的是json格式 如果需要使用gson和fastjson其中一种格式的话 首先需要在pom文件中排除对json格式的依赖 再去引入你想要gson或者fastjson
  • CSS样式——div居中方法

    1 绝对居中 给div设置样式 div默认显示位置为body的左上方 width 400px height 300px background color orange 如下图所示 首先给div添加绝对定位 并设置上下左右边距为0 然后使用m
  • 【git国内镜像地址】【速度快】

    重申一下 此处说的是git客户端下载 而不是github网站 github网站请绕路 git官网地址 官网地址 大家可以打开试试 每秒几十或者只有几kb 下完要一个月 大家可以试试国内地址 5秒之内下载完成 git国内镜像地址 git国内镜
  • C++泛型基础

    1 泛型的基本思想 泛型编程 Generic Programming 是一种语言机制 通过它可以实现一个标准的容器库 像类一样 泛型也是一种抽象数据类型 但是泛型不属于面向对象 它是面向对象的补充和发展 在面向对象编程中 当算法与数据类型有