第十二站(20天):C++泛型编程
模板
C++提供了模板(template)编程的概念。所谓模板,实际上是建立一个通用函数或类, 其类内部的类型和函数的形参类型不具体指定 ,用一个虚拟的类型来代表。这种通用的方式称为模板。 模板是泛型编程的基础, 泛型编程即以一种独立于任何特定类型的方式编写代码如: vector
函数模板(可以嵌套使用)
模板函数就是函数模板的自动实现
功能:使用函数体相同的函数都可以用这个模板替代实现多个函数用来返回两个数的最大值,要求能支持 char 类型、int 类型、doubletemplate <typename T>如:template <typename T>//这里的类属参数 T在下面函数体的 参数中必须出现一次
T Max(T a, T b) {
return a > b ? a : b;
}形式:cout << Max(a, b) << endl;//编译器自动推导类型
cout << Max<int>(a,b)<<endl;//显示类型调用
#include <iostream>
using namespace std;template <typename T>
T Max(T a, T b) {return a > b ? a : b;
}
int main(void) {int a = 4;int b = 5;float x = 1.2f;float y = 2.6f;cout << Max(a, b) << endl;//编译器自动推导类型cout << Max<int>(a,b)<<endl;//显示类型调用cout << Max(x, y) << endl;return 0;
}
函数模板和函数重载
//当函数模板和普通函数都符合调用时,优先选择普通函数//Max(a,b);//如果 显式指定类型 的使用函数模板,则使用<> 类型列表//Max<>(a, b);//如果函数模板会产生更好的匹配,使用函数模板
函数模板的调用机制
函数模板在调用的时候,会根据调用者的数据类型,创建一个匹配的函数
类模板
类模板和函数模板一致
在类使用数据类型的地方都可以用模板的类属参数进行替换
(成员数据的数据类型,构造函数的参数类型,成员函数的返回值类型)
注:在模板类定义对象的时候必须指定为显示指定类型<>
当为单个参数时:
#include <iostream>
using namespace std;
template <typename T>
class A {
public:A(T a) {this->a = a;}T getA() {return a;}
private:T a;
};int main(void) {A<int> aa(666);cout << aa.getA() << endl;return 0;
}
当为多个参数时

#include <iostream>
using namespace std;
template <typename T1,typename T2>
class A {
private:T1 a;T2 b;
public:A(T1 a ,T2 b) {this->a = a;this->b = b;}T1 getA() {return a;}T2 getB() {return b;}
};int main(void) {A<int, double> aa(12,4.5);cout << aa.getA() << endl;cout << aa.getB() << endl;return 0;
}
当类作为函数参数的时候
double add(A<int, double>& a) {
double sum = 0;
sum = a.getA() + a.getB();
return sum;
}
当子类继承父类(父类为模板类时)
class B :public A<int, double> {
B(int a, double b):A(a,b) {}
};
当子类是模板类,父类是一般类时
和普通继承一样
#include <iostream>
using namespace std;class B {
protected:int a;double b;
public:B(int a=1, double b=1.2) {this->a = a;this->b = b;}
};template <typename T1, typename T2>
class A :public B{
public:A();A(T1 a, T2 b) :B(a, b) {}T1 getA() {return a;}T2 getB() {return b;}
};double add(A<int, double>& a) {double sum = 0;sum = a.getA() + a.getB();return sum;
}
int main(void) {A<int ,double> aa(12,12.2);cout << aa.getA() << endl;cout << aa.getB() << endl;return 0;
}
当子类和父类都是模板类
和普通继承一样

#include <iostream>
using namespace std;template <typename T1, typename T2>
class B {
public:B(T1 a, T2 b){this->a = a;this->b = b;}T1 getA() {return a;}T2 getB() {return b;}
protected:T1 a;T2 b;
};template <typename T1, typename T2>
class A :public B<int, double>{
public:A();A(T1 a, T2 b) :B(a, b) {}T1 getA() {return a;}T2 getB() {return b;}
};double add(A<int, double>& a) {double sum = 0;sum = a.getA() + a.getB();return sum;
}
int main(void) {A<int, double> aa1(10, 10.2);cout << aa1.getA() << endl;cout << aa1.getB() << endl;A<int ,double> aa(12,12.2);cout << aa.getA() << endl;cout << aa.getB() << endl;return 0;
}
类模板和友元函数
(1) 类内部声明友元函数,必须写成一下形式template < typename T>friend A<T> addA (A<T> &a, A<T> &b);(2) 友元函数实现 必须写成template < typename T>A<T> add(A<T> &a, A<T> &b) {//......}(3) 友元函数调用 必须写成A< int > c4 = addA <int> (c1, c2);
类模板的封装
这里仅分为两个文件(.h和.cpp+main.cpp)

函数前声明 template< 类型形式参数表 >类的成员函数前的 类限定域说明必须要带上虚拟参数列表template<typename T1>
A<T1>::A(T1 a)
{
this->a = a;
}返回的变量是模板类的对象时必须带上虚拟参数列表T1 A<T1>::getA() {
return a;
}成员函数参数中出现模板类的对象时必须带上虚拟参数列表(也可以不带)A<T1> A<T1>::operator+( const A<T1> & other)
{
A<T1> tmp = this->a + other.a;
return tmp.a;
}成员函数内部没有限定( 可带可以不带 )A<T1> A<T1>::operator+( const A<T1> & other)
{
A<T1> tmp = this->a + other.a;
return tmp.a;
}
类模板封装单参:
.h
#include <iostream>
using namespace std;template <typename T1>
class A {
public:A(T1 a);T1 getA();A operator+(const A& other);void print();
private:T1 a;
};.cpp
#include <iostream>
using namespace std;
#include "A.h"template<typename T1>
A<T1>::A(T1 a)
{this->a = a;
}
template <typename T1>
T1 A<T1>::getA() {return a;
}
template<typename T1>
A<T1> A<T1>::operator+(const A& other)
{A tmp = this->a + other.a;return tmp.a;
}template<typename T1>
void A<T1>::print()
{cout << this->a << endl;
}
int main(void) {A<int> a(12);A<int> b(11);A<int> c = a + b;c.print();return 0;
}
这里仅分为三个文件(.h 和 .cpp 和 main.cpp)
如果分为这三个文件,那么只包含.h头文件就会报错C++ 类模板“无法解析的外部符号
在封装有三个文件的时候mian.cpp中就不用包含.h头文件了,仅包含.cpp文件即可
#include <iostream>
using namespace std;//#include "A.h"//同时包含两个或者仅包含.h都会报错
#include "A.cpp"int main(void) {
A<int> a(12);
A<int> b(11);
A<int> c = a + b;
c.print();
return 0;
}
类模板封装多参
算术运算符重载多参
template<typename T1, typename T2>
A1<T1, T2> A1<T1, T2>::operator+(const A1<T1,T2>& other)
{
A1<T1, T2> tmp{ this->a + other.a,this->b + other.b };
return tmp;
}输出运算符重载多参
template<typename T1, typename T2>
friend ostream& operator<<(ostream& os, const A1<T1, T2>& other);//设置为友元template<typename T1, typename T2>
ostream& operator<<(ostream& os, const A1<T1, T2>& other)
{
//“T1 A1<T1,double>::getA(void)”:
// 不能将“this”指针从“const A1<int,double>”转换为“A1<int,double>
//是因为传入的是const引用,但是调用了非const方法。
os << other.getA() << " " << other.getB() << endl;
//os << other.a <<" " << other.b << endl;
return os;
}
.h
#pragma once#include <iostream>
using namespace std;template <typename T1, typename T2>
class A1 {
public:A1(T1 a, T2 b);T1 getA()const;T2 getB()const;A1<T1, T2> operator+(const A1& other);template<typename T1, typename T2>friend ostream& operator<<(ostream& os, const A1<T1, T2>& other);
public:T1 a;T2 b;
};template<typename T1, typename T2>
ostream& operator<<(ostream& os, const A1<T1, T2>& other)
{os << other.getA() << " " << other.getB() << endl;//os << other.a <<" " << other.b << endl;return os;
}
.cpp
#include "A1.h"
#include <iostream>
using namespace std;
template<typename T1, typename T2>
A1<T1, T2>::A1(T1 a, T2 b):a(a),b(b)
{
}
template <typename T1, typename T2>
T1 A1<T1, T2>::getA() const{return a;
}
template<typename T1, typename T2>
T2 A1<T1, T2>::getB()const {return b;
}template<typename T1, typename T2>
A1<T1, T2> A1<T1, T2>::operator+(const A1<T1,T2>& other)
{A1<T1, T2> tmp{ this->a + other.a,this->b + other.b };return tmp;
}
主函数
#include <iostream>
#include "A1.cpp" //这里不要包含错了
int main(void) {A1<int, double> a(12, 3.3), b(13, 32.9);A1<int, double> c = a + b;cout << c << endl;return 0;
}
类模板的静态成员数据
从类模板实例化的每个模板类有自己的类模板数据成员,该 模板类的所有对象共享一个 static 数据成员和非模板类的 static 数据成员一样, 模板类的 static 数据成员也应该在文件范围定义和初始化static 数据成员也可以使用虚拟类型参数 T
public:
static T1 count;
//初始化静态成员数据
template<typename T1>
T1 A<T1>::count = 66;//通过对象a对静态count赋值后
cout << a.count << endl;
a.count = 888;
cout << b.count << endl;
b.count = 1000;
cout << a.count << endl;

相关文章:
第十二站(20天):C++泛型编程
模板 C提供了模板(template)编程的概念。所谓模板,实际上是建立一个通用函数或类, 其 类内部的类型和函数的形参类型不具体指定 ,用一个虚拟的类型来代表。这种通用的方式称 为模板。 模板是泛型编程的基础, 泛型编程即以一种独立于任何特定…...
【Docker】Dokcer学习① - 简介
【Docker】Docker学习① - 简介 一、Docker简介1. Docker是什么2. Docker组成3. Docker对比虚拟机4. Linux Namespace技术5. Linux control groups6. 容器管理工具 二、Docker安装及基础命令介绍三、Docker镜像管理四、Docker镜像与制作五、Docker数据管理六、网络部分七、Dock…...
PostgreSQL 100条命令
我会为您提供一些 PostgreSQL 中最常用的命令: 1. 创建数据库:CREATE DATABASE database_name; 2. 连接到数据库:\c database_name; 3. 创建表格:CREATE TABLE table_name (column1 datatype, column2 datatype, ...); 4. 插入数…...
HTTP动态代理的原理及其对网络性能的影响
HTTP动态代理是一种通过代理服务器来转发HTTP请求和响应数据的网络技术,它可以优化网络性能、提高网络安全性,并解决跨域请求的问题。本文将详细介绍HTTP动态代理的原理及其对网络性能的影响。 一、HTTP动态代理的原理 HTTP动态代理的基本原理是在客户…...
69.使用Go标准库compress/gzip压缩数据存入Redis避免BigKey
文章目录 一:简介二:Go标准库compress/gzip包介绍ConstantsVariablestype Headertype Reader 三:代码实践1、压缩与解压工具包2、单元测试3、为何压缩后还要用base64编码 代码地址: https://gitee.com/lymgoforIT/golang-trick/t…...
JavaScript实现的一些小案例
小案例 灯开关案例 <body><img id"light" src"img/off.jpg"><script>var light document.getElementById("light");var flag false;if(flag){light.src "img/on.jpg";flag false;}else{light.src "img/…...
MVC模式
Model-View-Controller : 模型-视图-控制器模式,用于应用程序的分层开发。 Model(模型):代表一个存取数据的对象。也可以带有逻辑,在数据变化时更新控制器。 View(视图):代表模型包含的数据的可视化。 Controller(控制器)…...
Java中的代理模式(一)
大家好👋,我是极客涛😎,今天我们聊一聊java中的代理模式,话不多说,还是老思路,什么是代理模式,为什么要有代理模式,如何实现代理模式 代理模式 在说java中的代理模式之前…...
跳跃游戏-算法
题目 给定一个数组nums {1,2,3,4,5},每个元素nums[i]表示从i这个位置最多可以向前跳跃nums[i]个台阶,求最小需要跳几次就可以调到末尾 思路 反向查找 从末尾开始逐个向前判断最远的起跳位置,接着再以该位置递归的判断 public int jumpT…...
ERP系统哪个好用?用友,金蝶,ORACLE,SAP综合测评
ERP系统哪个好用?用友,金蝶,ORACLE,SAP综合测评 ERP领域SAP、ORACLE相对于国内厂商如用友、金蝶优势在哪? SAP,ORACLE操作习惯一般国人用不惯;相对于国产软件,界面也很难看&#x…...
外汇天眼:美国证券交易委员会(SEC)采纳了一系列规定,以加强与特殊目的收购公司(SPACs)相关的投资者保护
美国证券交易委员会(SEC)今天通过了一系列新规和修订,以增强特殊目的收购公司(SPACs)的首次公开募股(IPOs)中的披露,并在SPACs与目标公司之间的后续业务合并交易(de-SPAC…...
kotlin map 与 flatmap
kotlin map 与 flatmap 是2个不同的概念的 map 是一种数据结构,flatmap 是一个高阶函数,处理集合用的 Map Map 是一种数据结构,它由一系列的键值对组成,每个键都是唯一的,并且与一个特定的值相关联。你可以通过键来…...
nginx-rtmp-module 支持 Enhancing RTMP HEVC(H.265)
Enhancing RTMP, FLV 2023年7月31号正式发布,主要支持了HEVC(H.265)、VP9、AV1视频编码,发布差不多半年了,很多开源项目已支持,最近打算播放和推送端也支持下,想找个支持的rtmp server方便测试用,但没找到合…...
2024最新JDK1.8+JDK17+JDK21安装包下载+文档
2024年更新,JDK8的64位和32位安装包都有,Java8最新文档也有,JDK17和JDK21的最新安装包也有 因为网上的安装包都不是最新的,所以自己去Oracle官网登录下载保存了一份,需要的朋友下面网盘链接下载 JDK8—64位安装程序&…...
如何利用chatgpt提升工作效率
chatgpt全领域小助手 项目管理:制定项目计划、跟踪进度、分配任务和记录里程碑。客户服务:回答常见问题、提供产品支持和处理客户投诉,提升客户满意度。销售支持:提供销售培训、销售脚本和客户资料,辅助销售团队进行销…...
WinSCP下载安装并实现远程SSH本地服务器上传文件
文章目录 1. 简介2. 软件下载安装:3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 Winscp是一个支持SSH(Secure SHell)的可视化SCP(Secure Copy)文件传输软件,它的主要功能是在本地与远程计…...
QEMU搭建arm虚拟机开发环境
获取QEMU代码 git clone https://gitlab.com/qemu-project/qemu.git 切换对应的工程分支 使用git指令切换到对应的分支上,我这里使用的是stable-4.0的分支 git checkout -b stable-4.0 remotes/origin/stable-4.0 配置&编译 在工程的根目录下执行 ./conf…...
web 应用常见的安全问题
一xss攻击 人们经常将跨站脚本攻击(Cross Site Scripting)缩写为CSS,但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆。因此,有人将跨站脚本攻击缩写为XSS。 跨站脚本攻击ÿ…...
502. IPO
502. IPO 题目链接:502. IPO 代码如下: //堆的使用 class Solution { public:int findMaximizedCapital(int k, int w, vector<int>& profits, vector<int>& capital) {vector<pair<int,int>> mp;//优先队列默认的是大…...
如何安装MeterSphere并实现无公网ip远程访问服务管理界面
文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
