【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
请按任意键继续. . .

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构 二叉树

二叉树 二叉树是n个有限元素的集合&#xff0c;该集合或者为空、或者由一个称为根&#xff08;root&#xff09;的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成&#xff0c;是有序树。当集合为空时&#xff0c;称该二叉树为空二叉树。在二叉树中&#xff0c;一个…

【8】Spring Boot 3 集成组件:安全组件 spring security【官网概念篇】

目录 【8】Spring Boot 3 集成组件&#xff1a;安全组件 spring securitySpring Security 简介先决条件引入依赖身份验证密码存储密码存储历史DelegatingPasswordEncoder密码存储格式密码加解密类自定义密码存储 体系结构 ArchitectureServlet 过滤器DelegatingFilterProxyFilt…

第二十章 多线程

20.2创建线程 20.2.1继承Thread类 Thread类是Java.lang包中的一个类&#xff0c;从这个类中实例化的对象代表线程&#xff0c;程序员启动一个新线程需要建议Thread实例。 public class ThreadTest extedns Thread{} run方法格式&#xff1a; public void run(){} 20.1让线程循…

mysql命令导出表结构和数据

MySQL是一款流行的关系型数据库管理系统&#xff0c;是许多公司和组织使用的首选数据库。在日常使用中&#xff0c;我们经常需要对数据库进行备份和复制&#xff0c;因此必须了解如何导出表结构和表数据。以下是使用MySQL命令导出表结构和表数据的方法。 1. 导出表结构 mysql…

AnalyticDB for PostgreSQL 实时数据仓库上手指南

AnalyticDB for PostgreSQL 实时数据仓库上手指南 2019-04-016601 版权 本文涉及的产品 云原生数据仓库 ADB PostgreSQL&#xff0c;4核16G 50GB 1个月 推荐场景&#xff1a; 构建的企业专属Chatbot 立即试用 简介&#xff1a; AnalyticDB for PostgreSQL 提供企业级数…

iOS合并代码后解决冲突

合并主干和分支代码后有冲突&#xff0c;xcode无法运行&#xff0c;如下图&#xff1a;文件显示不了&#xff0c;项目名也显示不了 解决冲突&#xff1a; 1.选中左边目录栏的项目名。鼠标右键--> Show in Finder 2.选中项目文件 xxxx.xcodeproj。鼠标右键--> 显示包内容…

【python学习】中级篇-绘制图形:turtle库

turtle库是Python的一个绘图库&#xff0c;它提供了一个简单的绘图窗口&#xff0c;可以让你通过控制一个小海龟在屏幕上移动来绘制图形。 以下是一个简单的turtle库用法示例&#xff1a; 在这个示例中&#xff0c;我们首先导入了turtle库&#xff0c;然后创建了一个画布和一个…

【创建一个C++线程需要传入几个参数?】

在C++中,创建一个std::thread对象时,你可以传递多个参数,但至少需要一个参数:线程将要执行的函数。这个函数可以是一个普通函数、一个类的成员函数,或者一个可调用对象(如lambda表达式)。除了要执行的函数之外,你还可以传递任何数量的参数,这些参数将被转发到线程函数…

idea手动导入maven包

当maven仓库中没有包时&#xff0c;我们需要手动导入jar到maven项目中 1.这里的maven设置成你自己安装的maven 2.查看pom.xml文件中maven&#xff0c;以下面为例 <dependency><groupId>com.jdd.pay</groupId><artifactId>mapi-sdk-v3</artifactId&…

零基础小白如何自学 Python 步骤和知识点?

Python是一种流行的编程语言&#xff0c;被广泛用于Web开发、数据分析、机器学习、人工智能等领域。如果你是零基础的Python初学者&#xff0c;不必担心&#xff0c;以下是一些建议&#xff0c;帮助你开始Python编程之旅。 黑马程序员python教程&#xff0c;8天python从入门到…

计网(复习自用)

计算机网络 1.概述 1.1概念 含义 计算机网络&#xff1a;是一个将分散的。具有独立功能的计算机系统&#xff0c;通过通信设备和线路连接起来&#xff0c;由功能完善的软件实现资源共享和信息传递的系统。 简单点说&#xff0c;计算机网络是互联的&#xff0c;自治的计算机集…

js方法(数组,对象,字符串,时间,内置方法等)

目录 1.数组方法 2. 对象方法 3. 字符串方法 4.数学方法 5. 日期和时间方法 6.内置方法 7.json方法 1.数组方法 push()&#xff1a;向数组末尾添加一个或多个元素&#xff0c;并返回新的长度。pop()&#xff1a;删除并返回数组的最后一个元素。unshift()&#xff1a;向数…

浅谈勒索病毒防护

免责声明 文章仅做经验分享用途&#xff0c;利用本文章所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任&#xff0c;一旦造成后果请自行承担&#xff01;&#xff01;&#xff01; 目录 免责声明 一&am…

使用Python调用API接口获取小红书笔记详情数据

本文将详细介绍如何使用Python编程语言调用小红书API接口&#xff0c;以获取小红书笔记的详情数据。我们将从以下几个方面展开讨论&#xff1a;1) API接口简介&#xff1b;2) Python环境准备&#xff1b;3) API密钥获取&#xff1b;4) 使用Requests库发送API请求&#xff1b;5)…

Android系统调试工具大全:解密adb、dumpsys、procrank等神器

Android系统调试工具大全&#xff1a;解密adb、dumpsys、procrank等神器 引言 Android开发中&#xff0c;调试是一个非常重要的环节&#xff0c;本文将介绍一些常用的Android系统调试工具&#xff0c;包括adb、logcat、procrank、dumpsys、dmesg、top、free、df、trace、pm、…

【python学习】基础篇-常用模块-hashlib模块:常见的哈希算法,如MD5、SHA1、SHA256等计算

Python中的hashlib模块提供了常见的哈希算法&#xff0c;如MD5、SHA1、SHA256等。 使用hashlib模块可以方便地计算字符串或文件的哈希值&#xff0c;常用于密码加密、数据完整性校验等场景。 以下是hashlib模块中一些常见哈希算法的用法&#xff1a; 在实际应用中&#xff0c;…

vue项目引入element-plus

文章目录 引入框架遇到的问题引入的时候&#xff0c;报错 ...(reading replace)...报错&#xff1a;The template root requires ...eslint报错&#xff1a; 运行 引入框架 使用add引入 遇到的问题 引入的时候&#xff0c;报错 …(reading ‘replace’)… Cannot read prop…

聊聊鼎叔的新书《无测试组织-测试团队的敏捷转型》

这是鼎叔的第八十篇原创文章。行业大牛和刚毕业的小白&#xff0c;都可以进来聊聊。 欢迎关注本公众号《敏捷测试转型》&#xff0c;星标收藏&#xff0c;大量原创思考文章陆续推出。 本书官方购买链接请点击 https://item.jd.com/14105386.html。 为何写作本书 对于“无测试组…

C#中委托和匿名方法

目录 一、委托 1.委托的实例化 2.委托的调用 3.示例 二、匿名方法 为了实现方法的参数化&#xff0c;提出了委托的概念&#xff0c;委托是一种引用方法的类型&#xff0c;即委托是方法的引用&#xff0c;一旦为委托分配了方法&#xff0c;委托将与该方法具有完全相同的行为…

DOM事件的传播机制

DOM事件的传播机制是指当一个事件在DOM树中触发时&#xff0c;它是如何在各个元素之间传播的。DOM事件传播机制分为三个阶段&#xff1a;捕获阶段、目标阶段和冒泡阶段。此外&#xff0c;还有一种常用的技术称为事件委托&#xff0c;它能够简化事件处理程序的绑定和管理。本文将…