当前位置: 首页 > news >正文

C++模板写法详解

模板

  • 概念
    • 模板就是建立通用的模具,大大提高复用性
  • 模板主要体现了cpp编程的另外一种思想泛型编程
  • cpp提供两种模板机制
    • 函数模板
    • 类模板
  • 函数模板
    • 作用
      • 建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表
    • 语法
        template<typename T>函数声明或定义//template 声明创建模版//typename 表面其后面的符号是一个数据类型,可以用class代替//T 通用数据类型,名称可替换
      
    • 使用语法
      • 自动类型推导
        • mySwap(a, b);
      • 显示指定类型
        • mySwap(a, b);
    • 举例
          #include<iostream>using namespace std;template<typename T>void mySwap(T& a, T& b){T temp = a;a = b;b = temp;}int main(){int a = 10;int b = 20;double c = 3.54;double d = 4.43;mySwap(a, b);mySwap<double>(c, d);cout << a << b << endl;cout << c << d << endl;return 0;}
      
      • 本质类型参数化
    • 注意事项
      • 自动类型推导,必须要推导出类型一致的数据类型T才可以使用
      • 模版必须要确定出T的数据类型,才可以使用
      • class可以用于函数也可以用于类typename只能用于函数
    • 普通函数与函数模板的区别
      • 普通函数调用时可以发生自动类型转换(隐式类型转换)
      • 函数模版调用时,如果利用自动类型推导,不会发生隐式类型转换
      • 如果利用显示制定类型的方式,可以发生隐式类型转换
    • 普通函数和函数模板的调用规则
      • 如果函数模板和普通函数都可以实现,优先调用普通函数
      • 可以通过空模板参数列表来强制调用函数模板
      • 函数模板也可以发生重载
      • 如果函数模板可以更好的匹配则优先调用函数模板
          myfunc<>(a, b)//空模板
      
    • 模板的局限性
      • 有些特定数据类型要用具体化方式做特殊实现
          #include<iostream>#include<string>using namespace std;class Person{public:string m_name;int m_age;Person(string name, int age){m_name = name;m_age = age;}//函数重载是一种方法// bool operator==(const Person& p){//     if(this->m_age == p.m_age && this->m_name == m_name)//         return true;//     else//         return false;// }};template<class T>void myCompare(T& a, T& b){if(a == b){cout << "same" << endl;}else{cout << "different" << endl;}}//利用具体化Person的版本实现代码,具体化优先调用template<>void myCompare(Person& a, Person& b){if(a.m_age == b.m_age && a.m_name == a.m_name)cout << "same" << endl;else    cout << "different" << endl;}void test(void){Person a("zhangsan",20);Person b("zhangsan", 10);myCompare(a, b);}int main(){test();return 0;}
      
  • 类模板
    • 类模板作用
      • 建立一个通用类,类中成员数据类型可以不具体制定,用一个虚拟的类型来表示
    • 语法
          template<typename T>
    • 简单举例
          #include<iostream>#include<string>using namespace std;template<class NameType, class AgeType>class Person{public:NameType m_name;AgeType m_age;Person(NameType name, AgeType age){this->m_age = age;this->m_name = name;}void ShowInfor(void){cout << "my name is " << this->m_name << endl;cout << "my age is " << this->m_age << endl;}};void test(void){Person<string, int>p("zhangsan", 18);//必须显式调用p.ShowInfor();}int main(){test();return 0;}
      
    • 类模板与函数模板的区别
      • 类模板没有自动推导的使用方式
      • 类模板在模板参数列表中可以有默认参数
        • template<class NameType, class AgeType = int>
    • 类模板中成员函数创建时机
      • 普通类中的成员函数一开始就可以创建
      • 类模板中的成员函数在调用时才创建
    • 类模板对象做函数参数—如何给函数传入类模板所创造的对象
      • 传入方式
        • 指定传入类型—直接显示对象的数据类型
        • 参数模板化—将对象中的参数变为模板进行传递
        • 整个类模板化—将这个对象类型模板化进行传递
      • 举例
        #include<iostream>
        #include<string>
        using namespace std;
        template<class NameType, class AgeType>
        class Person{public:NameType m_name;AgeType m_age;Person(NameType name, AgeType age){this->m_age = age;this->m_name = name;}void ShowInfor(void){cout << "my name is " << this->m_name << endl;cout << "my age is " << this->m_age << endl;}
        };
        //指定传入类型---最常用
        void Personshow1(Person<string, int> &p){p.ShowInfor();
        }
        void test1(void){Person<string, int>p("zhangsan", 18);Personshow1(p);
        }
        //参数模板化
        template<class T1, class T2>
        void Personshow2(Person<T1, T2> &p){p.ShowInfor();
        }
        void test2(void){Person<string, int>p("zhangsan", 28);Personshow2(p);
        }
        // 整个类型模板化
        template<class T>
        void Personshow3(T &p){p.ShowInfor();
        }
        void test3(void){Person<string, int>p("zhangsan", 38);Personshow3(p);
        }
        int main(){test1();test2();test3();return 0;
        }
        
    • 类模板与继承
      • 当子类继承的父类是一个类模板时,子类在声明时候,要指出父类中T的类型
      • 如果不指定,编译器无法给子类分配内存
      • 如果想灵活指定出父类中T的类型,子类也需变为类模板
      • 简单例子
            #include<iostream>#include<string>using namespace std;template<class T>class Base{public:T name;};//第一种继承方法class Son1: public Base<string>{public:void showInfor(void){cout << "my name is " << this->name << endl;        }};// 第二种方法进一步扩大模板template<class T1, class T2>class Son2: public Base<T1>{public:T2 age;void showInfor(void){cout << "my name is " << this->name << endl; cout << "my age is " << this->age << endl;       }};void test1(void){Son1 s;s.name = "zhangsan";s.showInfor();}void test2(void){Son2<string, int>s;s.name = "zhangsan";s.age = 18;s.showInfor();}int main(){test1();test2();return 0;}
        
    • 类模板中的成员函数的类外实现
      • 普通的类外实现
            #include<iostream>#include<string>using namespace std;class Person1{public:void printInfor(void);};void Person1::printInfor(void){cout << "this is the test" << endl;}int main(){Person1 P1;P1.printInfor();return 0;}
        
    • 模板的类外实现
      #include<iostream>
      #include<string>
      using namespace std;
      template<class T>
      class Person1{public:T m_name;Person1(T name);void printInfor(void);
      };
      template<class T>//即使不用T也要添加这个列表
      Person1<T>::Person1(T name){this->m_name = name;
      }
      template<class T>//即使不用T也要添加这个列表
      void Person1<T>::printInfor(void){cout << "this is the test" << endl;
      }
      int main(){Person1<string>P1("zhangsan");P1.printInfor();return 0;
      }
      
      • 总结
        • 主要是要同步声明其为模板
        • 在定义过程的最开始要加入模板列表
    • 类模板分文件编写
      • 问题
        • 类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到
      • 解决
        • 直接包含cpp文件
          • 一般我们include的都是.h文件,此处可以改为.cpp文件
          • 原因
            • 模板类不会一开始就生成,因此包含.h并没有什么用
        • 将声明和实现写在同一个文件中,并更改后缀名为.hpp,这是约定不是强制,用于实现类模板的实现
    • 类模板与友元
      • 掌握类模板配合友元函数的类内和类外实现
      • 全局函数类内实现—直接在类内声明友元即可—推荐—直接加入friend然后定义即可
      • 全局函数的类外实现—需要提前让编译器知道全局函数的存在

相关文章:

C++模板写法详解

模板 概念 模板就是建立通用的模具&#xff0c;大大提高复用性 模板主要体现了cpp编程的另外一种思想泛型编程cpp提供两种模板机制 函数模板类模板 函数模板 作用 建立一个通用函数&#xff0c;其函数返回值类型和形参类型可以不具体制定&#xff0c;用一个虚拟的类型来代表 语…...

【备战面试】每日10道面试题打卡-Day2

本篇总结的是Java基础知识相关的面试题&#xff0c;后续也会更新其他相关内容 文章目录1、 和 equals 的区别是什么&#xff1f;2、你重写过 hashcode 和 equals 吗&#xff0c;为什么重写equals时必须重写hashCode方法&#xff1f;3、为什么Java中只有值传递&#xff1f;4、BI…...

“数字档案室测评”相关参考依据梳理

数字档案室建设无疑比数字档案馆建设应用范围更为广泛&#xff0c;涉及的单位类型和专业领域也更多。这一点从国家档案局的机构设置上也可以看出端倪&#xff1a; 国家档案局两个内设业务指导司中&#xff0c;档案馆(室)业务指导司主要针对档案馆和机关档案室&#xff0c;而经济…...

android 动态加载jar包

什么时候需要用到动态加载jar包呢&#xff1f; 减少apk本身大小&#xff0c;某些界面才需要用jar里的功能jar中的功能可以独立开发&#xff0c;不要依赖其它的东西&#xff0c;能适用各个项目和第三方公司合作&#xff0c;人家不提供项目源码给你&#xff0c;但又要开发他们使…...

JAVA版B2B2C商城源码多商户入驻商城

三勾商城多商户是开发友好的微信小程序商城&#xff0c;框架支持SAAS&#xff0c;支持发布 iOS Android 公众号 H5 各种小程序&#xff08;微信/支付宝/百度/头条/QQ/钉钉/淘宝&#xff09;等多个平台&#xff0c;不可多得的二开神器&#xff0c; 为大中小企业提供极致的移…...

测试人员如何在测试环境数据库批量生成测试数据?方案分享

测试人员为了测试某个特定场景&#xff0c;往往需要在测试环境数据库中插入特定的测试数据来满足需求&#xff1b;性能测试时&#xff0c;常需要在测试环境生成大量可用测试数据来支持性能测试&#xff1b;建设持续集成持续交付体系时&#xff0c;我们往往也需要在测试环境生成…...

【el】表单

elementUI中的表单相关问题一、用法1、动态表单调用接口返回表单&#xff0c;后端的接口返回值如下&#xff1a;这些是渲染后的效果页面使用&#xff08;父组件&#xff09;<el-button size"small" class"Cancelbtn" click"sub(true)">发起…...

【Flutter入门到进阶】Flutter基础篇---布局

1 GridView网格布局组件 1.1 说明 1.1.1 图例 1.1.2 说明 GridView网格布局在实际项目中用的也是非常多的&#xff0c;当我们想让可以滚动的元素使用矩阵方式排列的时 候。此时我们可以用网格列表组件GridView实现布局 GridView创建网格列表主要有下面三种方式 1、可以通过Gr…...

python海龟绘图

一、基础 &#xff08;一&#xff09;介绍 海龟绘图&#xff08;Turtle Graphics&#xff09;&#xff1a;“小海龟”turtle是Python语言中一个很流行的绘制图像的函数库&#xff0c;想象一个小乌龟&#xff0c;在一个横轴为x、纵轴为y的坐标系原点&#xff0c;(0,0)位置开始…...

【计算机网络】数据链路层

概述 封装成帧 差错检验 可靠传输 实现机制 可靠传输的实现机制 停止等待协议 回退N帧协议 选择重传协议 【计算机网络】MAC帧和PPP帧&#xff08;定义使用范围区别共同点&#xff09;_GPNU_Log的博客-CSDN博客_ppp帧 PPP帧和以太网帧 | Mixoo 数据链路层的协议有PPP协…...

使用groovy代码方式解开gradle配置文件神秘面纱

来到这里的是不是都有以下疑问&#xff1a; 1.build.gradle配置文件结构好复杂啊&#xff0c;怎么记&#xff1f; 2.内部是怎么进行分析和执行的&#xff1f; 3.为什么可以在配置文件里面写groovy代码&#xff0c;怎么识别的&#xff1f; 4.怎么才能很方便的记住和快速上手…...

kafka入门到实战二(使用docker搭建kafka集群)

使用Docker搭建kafka单机/集群 拉取镜像&#xff1a;2.8.0之前&#xff0c;kafka都需要依赖zookeeper docker pull wurstmeister/kafka docker pull wurstmeister/zookeeper运行zookeeper镜像 docker run -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeper运行ka…...

【简化开发】lombok的使用、编译后的代码及源码

lombok的使用导入依赖一、getter、Setter、toString1、getter、Setter分别生成getxxx()和setxxx()方法2、toString生成toString()方法&#xff0c;按顺序打印类名称以及每个字段&#xff0c;并以逗号分隔二、NoArgsConstructor、RequiredArgsConstructor、AllArgsConstructor1、…...

在线就能用的主图设计素材,免费分享!

如何给自己的店铺商品设计专属的节日活动主图&#xff1f;没有节日活动的主体素材要如何设计&#xff1f;下面小编就分享一个在线素材设计工具&#xff0c;打开乔拓云&#xff0c;平台里面不仅有许多能使用的电商设计素材&#xff0c;还有许多的设计工具和模板能帮助你快速的实…...

【测绘程序设计】——计算卫星位置

本文分享了根据广播星历计算卫星于瞬时地固系下位置的计算程序(C#版)(注:瞬时地球坐标系坐标经极移改正即可获得协议地球坐标系坐标),相关源代码(完整工程,直接运行;包含实验数据)及使用示例如下。 目录 Part.Ⅰ 使用示例Part.Ⅱ 代码分析Chap.Ⅰ 数据结构Chap.Ⅱ 计…...

山东双软认证的基本条件

​一、山东双软认证的基本条件 "双软认证"是指软件产品评估和软件企业评估;企业申请双软认证除了获得软件企业和软件产品的认证资质&#xff0c;同时也是对企业知识产权的一种保护方式&#xff0c;更可以让企业享受国家提供给软件行业的税收优惠政策&#xff1b;我们…...

TPM 2.0实例探索3 —— LUKS磁盘加密(4)

接前文&#xff1a;TPM 2.0实例探索2 —— LUKS磁盘加密&#xff08;3&#xff09; 本文大部分内容参考&#xff1a; Code Sample: Protecting secret data and keys using Intel Platform... 二、LUKS磁盘加密实例 4. 将密码存储于TPM的PCR TPM平台配置寄存器&#xff08;…...

Linux连接RDP远程服务工具集记录

目录 rdesktop 安装 实例 xfreerdp 安装 实例 remmia 介绍 rdesktop 安装...

离散事件动态系统

文章目录离散事件动态系统ppt离散事件系统建模离散事件动态系统的基本组成元素离散事件动态系统仿真具体建模petri建模实例离散事件动态系统 ppt ppt 仿真建模步骤 离散事件系统建模 from&#xff1a;离散事件系统建模 离散事件动态系统的基本组成元素 &#xff08;1&am…...

无线WiFi安全渗透与攻防(二)之打造专属字典

系列文章 无线WiFi安全渗透与攻防(一)之无线安全环境搭建 打造专属字典 什么在破解之前先准备专用字典&#xff0c;因为对于一般家庭来说&#xff0c;常用 一个是预共享密钥PSK&#xff0c;一个是PIN码。 也不是所有的路由都开起了PIN码&#xff0c;一般都会开启域共享密钥…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...

Ubuntu系统多网卡多相机IP设置方法

目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机&#xff0c;交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息&#xff0c;系统版本&#xff1a;Ubuntu22.04.5 LTS&#xff1b;内核版本…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

五子棋测试用例

一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏&#xff0c;有着深厚的文化底蕴。通过将五子棋制作成网页游戏&#xff0c;可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家&#xff0c;都可以通过网页五子棋感受到东方棋类…...