【C++】泛型编程 ⑫ ( 类模板 static 关键字 | 类模板 static 静态成员 | 类模板使用流程 )

文章目录

  • 一、类模板使用流程
    • 1、类模板 定义流程
    • 2、类模板 使用
    • 3、类模板 函数 外部实现
  • 二、类模板 static 关键字
    • 1、类模板 static 静态成员
    • 2、类模板 static 关键字 用法
    • 3、完整代码示例


将 类模板 函数声明 与 函数实现 分开进行编码 , 有 三种 方式 :

  • 类模板 的 函数声明 与 函数实现 都写在同一个类中 , 也就是没有分开进行编码 ;
  • 类模板 的 函数实现 在 类外部进行 , 函数声明 和 实现 写在相同的 .cpp 源码文件中 ;
  • 类模板 的 函数实现 在 类外部进行 , 函数声明 和 实现 写在不同的 .h 和 .cpp 源码文件中 ;

在博客 【C++】泛型编程 ⑨ ( 类模板的运算符重载 - 函数声明 和 函数实现 写在同一个类中 | 类模板 的 外部友元函数问题 ) 中实现了第一种情况 , 类模板 的 函数声明 与 函数实现 都写在同一个类中 , 也就是没有分开进行编码 ;

在博客 【C++】泛型编程 ⑩ ( 类模板的运算符重载 - 函数实现 写在类外部的同一个 cpp 代码中 | 类模板 的 外部友元函数二次编译问题 ) 中 , 分析了 第二种情况 , 类模板 的 函数实现 在 类外部进行 , 写在 一个 cpp 源码文件中 ;

在博客 【C++】泛型编程 ⑪ ( 类模板的运算符重载 - 函数实现 写在类外部的不同的 .h 头文件和 .cpp 代码中 ) 中 , 分析 第三种 情况 , 函数实现 在 类外部进行 , 函数声明 和 实现 写在不同的 .h 和 .cpp 源码文件中 ;





一、类模板使用流程




1、类模板 定义流程


类模板 定义流程 :

  • 首先 , 定义一个 使用 实际数据类型 的类 , 这里的数据类型 指的是 成员变量类型 或 成员函数 参数或返回值 类型 ; 这些类型 由于是 实际类型 , 语义明确 , 含义清楚 , 不会报错 ;
  • 然后 , 将 要使用 泛型模板 的 类型 , 改为一个 自己定义的 虚拟泛型类型 , 如 : template <typename T> 中的 T 类型 ;
  • 最后 , 在 类声明 前面加上 template <typename T> , 其中的 T 类型可以改为其它字母代替 , 一般是大写字母 ;

2、类模板 使用


使用类模板 : 使用 类模板 创建实例对象时 , 首先要注明 具体类型 , 生成具体类 , 才能创建具体类的 实例对象 , 语法格式如下 ;

类模板名称<实际类型名称> 对象名称;
类模板名称<实际类型名称> 对象名称(构造函数实参列表);

以 上一篇博客的 Student 类模板为例 , 创建 Student 类模板实例对象示例如下 ;

Student<int> s;
Student<int> s(1, 2);

3、类模板 函数 外部实现


如果要在 类模板 之外 实现 类模板中的 成员函数 ,

首先 ,声明 类模板 的类型参数 ;

template <typename 类型参数列表>

然后 , 使用 域操作符 :: 访问类模板中的函数 , 访问时需要 注明 类模板的 实际参数类型 ;

函数返回值类型 类模板名称<实际参数类型列表>::成员函数名(函数形参列表)
{
} 

特别注意 , 如果上面的类型中 , 涉及到的 函数返回值类型 或 函数形参列表 中 , 有 类模板类型 , 也要注明 实际的参数类型 ;


如下面的 operator+ 函数 ,

template <typename T>
class Student
{
public:
	// 重载 + 运算符
	Student operator+(Student& s);
};

在 类模板 外部 实现上述 函数声明 , 就需要使用如下方式 ;

// 重载 + 运算符
// 使用  Student<T>:: 域操作符访问函数
template <typename T>
Student<T> Student<T>::operator+(Student<T>& s)
{
	// 函数内部的类的 <T> 模板类型 , 可加 Student<T> 可不加 Student
	// 不加 <T> 也可以使用 , 加了也不会报错
	Student student(this->a + s.a, this->b + s.b);
	return student;
}




二、类模板 static 关键字




1、类模板 static 静态成员


类模板中 , 定义了 static 静态成员变量 ;

静态 成员变量 是属于整个类的 , 但是对于 类模板 来说 , 存在着二次编译 , 会生成多个不同的实际类 ;


类模板 的 实际类型 可能有多种 , 如 Student<int>Student<double> 是两个具体的实际类型 , C++ 编译器会将 类模板 编译成 两个不同的 类 ;

上述 编译成的 不同的类 , 每个类 都有一个 static 静态成员 , 相互之间是独立的 ;


2、类模板 static 关键字 用法


类模板 static 关键字 用法 :

首先 , 在 类模板 中 , 声明 static 静态成员 ;

template <typename T>
class Student
{
public:
	// 类模板中的静态成员
	static T m_a;
};

然后 , 在类外部 , 初始化静态成员 , 之后才能 使用该静态成员 , 使用 静态成员 时 , 要声明 类模板 类型 template <typename T> , 下面使用 域作用符 访问时 , 需要注明 类模板类型 ;

// 初始化静态成员
template <typename T>
T Student<T>::m_a = 0;

最后 , 使用 类模板 中的静态成员时 , 每个 生成的 具体类型 , 都有一个独立互不干扰的 静态成员 ; 下面 Student<int> 类型的对象 s1 , s2 共享 静态成员 m_a , Student<double> 类型的对象 s3 , s4 共享 静态成员 m_a ; s1 和 s3 是不同的静态成员 ;

Student<int> s1, s2;
Student<double> s3, s4;

3、完整代码示例


代码示例 :

#include "iostream"
using namespace std;

template <typename T>
class Student
{
public:
	// 类模板中的静态成员
	static T m_a;
};

// 初始化静态成员
template <typename T>
T Student<T>::m_a = 0;

int main() {
	Student<int> s1, s2;
	cout << "s1, s2 赋值前 : s1.m_a : " << s1.m_a << " , s2.m_a : " << s2.m_a << endl;

	s1.m_a = 6;
	cout << "s1, s2 赋值后 : s1.m_a : " << s1.m_a << " , s2.m_a : " << s2.m_a << endl;

	Student<double> s3, s4;
	cout << "s3, s4 赋值前 : s3.m_a : " << s3.m_a << " , s4.m_a : " << s4.m_a << endl;
	s3.m_a = 8;

	cout << "s3, s4 赋值后 : s1.m_a : " << s1.m_a << " , s2.m_a : " << s2.m_a << endl;
	cout << "s3, s4 赋值后 : s3.m_a : " << s3.m_a << " , s4.m_a : " << s4.m_a << endl;


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
}

执行结果 :

s1, s2 赋值前 : s1.m_a : 0 , s2.m_a : 0
s1, s2 赋值后 : s1.m_a : 6 , s2.m_a : 6
s3, s4 赋值前 : s3.m_a : 0 , s4.m_a : 0
s3, s4 赋值后 : s1.m_a : 6 , s2.m_a : 6
s3, s4 赋值后 : s3.m_a : 8 , s4.m_a : 8
请按任意键继续. . .

在这里插入图片描述

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

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

相关文章

linux ld 链接器学习笔记

ld链接器笔记 1. 首先编写一段汇编代码 这里的汇编语法时 AT&T语法,是gcc原生支持的语法,底层使用 gas(gnu assembler) 完成汇编,相较于 Intel x86语法, AT&T 语法要更加古老,因此大多数人更加偏向于使用 Intel 的语法. nasm 编译器支持x86语法.自从2.10版本&#xf…

问鼎web服务

华子目录 www简介常见Web服务程序介绍&#xff1a;服务器主机主要数据浏览器网址及http介绍urlhttp请求方法 http协议请求的工作流程www服务器类型静态网站动态网站 快速安装Apache安装准备工作httpd所需目录主配置文件 实验操作 www简介 Web网络服务也叫www&#xff08;world…

晶振有哪几种?晶振旁边的两个电容起什么作用?

晶振可以分为普通晶振、温补晶振、压控晶振、恒温晶振、差分晶振。 普通晶振通常用作微处理器的时钟器件&#xff0c;主要应用于那些稳定度要求不要的设备中&#xff0c;例如电视机、微波炉。 温补晶振&#xff0c;在晶振内部采取了对晶体频率、温度特性进行补偿&#xff0c;已…

Vue3常用操作

一、Vue3项目构建 1、安装最新版本vue npm create vuelatest 2、选择需要的配置 3、进入项目 cd 项目名称 4、下载依赖 npm install 5、启动项目 npm run dev

数据结构—链表

链表结构-----“银行自助叫号” 链表&#xff08;Linked List&#xff09;是一种常见的数据结构&#xff0c;用于存储一个序列的元素。它由一系列结点组成&#xff0c;每个结点包含两个部分&#xff1a;数据部分和指针部分。数据部分存储着当前结点的数据&#xff0c;而指针部分…

CSDN最新最全pytest系列——pytest-base-url插件之配置可选的项目系统UR

前言 ①当我们的自动化代码完成之后&#xff0c;通常期望可以在不同的环境进行测试&#xff0c;此时可以将项目系统的URL单独拿出来&#xff0c;并且可以通过pytest.ini配置文件和支持pytest命令行方式执行。 ② pytest-base-url 是一个简单的pytest插件&#xff0c;它通过命…

12-25v转3.3v高清水下钓鱼摄像头电源供电芯片方案

高清水下钓鱼摄像头电源芯片方案&#xff1a;12-25V转3.3V&#xff0c;支持超宽电压输入范围和30米长线视频放大 在水下钓鱼摄像头设计中&#xff0c;为了实现高清画质和稳定的电源供应&#xff0c;需要一款能够将12-25V转换为3.3V输出的高效电源芯片。这款电源芯片不仅支持高…

【电路笔记】-电流源

电流源 文章目录 电流源1、概述1.1 理想电流源1.2 实际电流源1.3 连接规则 2、依赖电流2.1 压控电流源2.2 电流控制电流源 3、总结 本文为前面文章 电压源的延续&#xff0c;我们将在本文介绍电流源。 与电压源的情况类似&#xff0c;我们将首先介绍理想电流源的概念&#xff…

第二十章:多线程

进程 线程的特点 1.进程是资源分配的最小单位&#xff0c;线程是最小的执行单位 2.一个进程可以有多个线程 3.线程共享进程资源 package twentyth; public class ThreadTest extends Thread { public void run() { for (int i 1; i < 10; i) {//继承重…

Shell判断:模式匹配:case(三)

系统管理工具箱 1、需求&#xff1a;Linux提供的丰富的管理命令&#xff0c;用户管理&#xff0c;内存管理&#xff0c;磁盘管理&#xff0c;进程管理&#xff0c;日志管理&#xff0c;文件管理&#xff0c;软件管理&#xff0c;网络管理等等数十个工具包。如果你能通过shell编…

二十、虚拟机网络配置

1、Linux网络配置原理 我自己Linux虚拟机的IP地址是&#xff1a;192.168.159.131 vmnet8&#xff1a;192.168.159.1 无线网卡&#xff1a;192.168.159.1 2、查看网络IP和网关 查看虚拟网络编辑器和修改IP地址 如果把这个位置的子网IP换成&#xff1a;192.168.8.0的话重启虚拟机…

【兔子王赠书第8期】AI短视频制作一本通: 文本生成视频+图片生成视频+视频生成视频

文章目录 写在前面推荐图书关键点内容简介作者简介推荐理由写在后面 写在前面 1本书精通AI短视频制作&#xff0c;文本生成视频图片生成视频视频生成视频AI短视频应用&#xff01;高效视频制作技巧&#xff0c;助你快速成长为行业大咖&#xff01; 推荐图书 《AI短视频制作一…

Java小游戏之飞翔的小鸟

创建三个包&#xff0c;存放代码。把图片放进文件中 APP包&#xff08;运行&#xff09; GameApp类 package APP; import mian.GameFrame;public class GameApp {public static void main(String[] args) {new GameFrame();} } mian包&#xff08;主内容&#xff09; Barrie…

SQL基础理论篇(九):存储过程

文章目录 简介存储过程的形式定义一个存储过程使用delimiter定义语句结束符存储过程中的三种参数类型流控制语句 存储过程的优缺点参考文献 简介 存储过程Stored Procedure&#xff0c;SQL中的另一个重要应用。 前面说的视图&#xff0c;只能勉强跟编程中的函数相似&#xff…

2023年危险化学品生产单位安全生产管理人员证模拟考试题库及危险化学品生产单位安全生产管理人员理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年危险化学品生产单位安全生产管理人员证模拟考试题库及危险化学品生产单位安全生产管理人员理论考试试题是由安全生产模拟考试一点通提供&#xff0c;危险化学品生产单位安全生产管理人员证模拟考试题库是根据危…

Unsupervised MVS论文笔记

Unsupervised MVS论文笔记 摘要1 引言2 相关工作3 实现方法 Tejas Khot and Shubham Agrawal and Shubham Tulsiani and Christoph Mertz and Simon Lucey and Martial Hebert. Tejas Khot and Shubham Agrawal and Shubham Tulsiani and Christoph Mertz and Simon Lucey and …

【java】想要限制每次查询的结果集不能超过10000行,该如何实现?

文章目录 前言 前言 对于一些Saas化软件&#xff0c;当某个租户在执行查询SQL时&#xff0c;如果查询条件出现了BUG&#xff0c;导致去查了所有租户的数据&#xff0c;这种情况是非常严重的&#xff0c;此时就需要在架构层面做限制&#xff0c;禁止一些特殊SQL的执行&#xff…

Axios 请求响应结果的结构

发送请求 this.$axios.get(https://apis.jxcxin.cn/api/title?urlhttps://apis.jxcxin.cn/,{params: {id: 10}}).then(res > {console.log(res)})输出返回结果 confing 请求时的配置对象&#xff0c;如果请求的url&#xff0c;请求的方法&#xff0c;请求的参数&#xff0c…

数字孪生助力污水处理升级

随着科技的发展&#xff0c;数字孪生技术在各行各业中得到了广泛应用。在污水处理领域&#xff0c;数字孪生技术为流程监控、效率提升、问题诊断等提供了强有力的支持。本文就借用山海鲸可视化软件的污水处理解决方案为大家介绍数字孪生在污水处理领域的作用。 一、实时监控 …

MAX/MSP SDK学习04:Messages selector的使用

其实消息选择器在simplemax示例中就接触到了&#xff0c;但这文档非要讲那么抽象。目前为止对消息选择器的理解是&#xff1a;可判断接收过来的消息是否符合本Object的处理要求&#xff0c;比如加法对象只可接收数值型的消息以处理&#xff0c;但不能接收t_symbol型的消息&…