C++ —— 模板类扩展

C++ —— 模板类扩展

  • 模板类的成员模板
  • 将模板类用作参数

模板类的成员模板

结构体中可以有结构体,类中可以有类和成员函数。那么,模板类中也应该可以有模板类模板函数
在类AA中再创建一个模板类模板函数
先创建模板类,代码如下:

#include <iostream>
using namespace std;template <class T1, class T2>
class AA {
public:    T1 m_x;T2 m_y;AA(const T1 x, const T2 y): m_x(x), m_y(y) {}void show() {cout << "AA的show ~ m_x = " << m_x << ", m_y = " << m_y << endl;}template <class T>class BB{public:T m_b;// 可以用AA的模板参数T1、T2创建成员变量T1 m_bx;BB() {}void show() {cout << "BB的show ~ m_b = " << m_b << ", m_bx = " << m_bx << endl;}};BB<string> bb; // 对象bb就是类模板AA的成员template <typename T> // 再创建一个函数模板,这个T和BB中的T没有关系void show(T t) {cout << "模板函数show ~ t = " << t << endl;cout << "AA ~ m_x = " << m_x << ", m_y = " << m_y << endl;bb.show();}
};int main() {AA<int, string> aa(123, "你好");aa.show();aa.bb.m_b = "哈哈";aa.bb.m_bx = 666;aa.bb.show();aa.show<string> ("嘻嘻嘻");return 0;
}

运行结果如下:

AA的show ~ m_x = 123, m_y = 你好
BB的show ~ m_b = 哈哈, m_bx = 666
模板函数show ~ t = 嘻嘻嘻
AA ~ m_x = 123, m_y = 你好
BB的show ~ m_b = 哈哈, m_bx = 666

模板类中的成员模板,定义可以写在类的外面。修改后的代码如下:

#include <iostream>
using namespace std;template <class T1, class T2>
class AA {
public:    T1 m_x;T2 m_y;AA(const T1 x, const T2 y): m_x(x), m_y(y) {}void show() {cout << "AA的show ~ m_x = " << m_x << ", m_y = " << m_y << endl;}template <class T>class BB{public:T m_b;// 可以用AA的模板参数T1、T2创建成员变量T1 m_bx;BB() {}void show();};BB<string> bb; // 对象bb就是类模板AA的成员template <typename T> // 再创建一个函数模板,这个T和BB中的T没有关系void show(T t);
};// 模板类中的成员模板,定义可以写在类的外面。
template <class T1, class T2>
template <class T>
void AA<T1, T2>::BB<T>::show() {{cout << "BB的show ~ m_b = " << m_b << ", m_bx = " << m_bx << endl;}
}template <class T1, class T2>
template <typename T>
void AA<T1, T2>::show(T t) {cout << "模板函数show ~ t = " << t << endl;cout << "AA ~ m_x = " << m_x << ", m_y = " << m_y << endl;bb.show();
}int main() {AA<int, string> aa(123, "你好");aa.show();aa.bb.m_b = "哈哈";aa.bb.m_bx = 666;aa.bb.show();aa.show<string> ("嘻嘻嘻");return 0;
}

运行结果跟之前保持一致:

AA的show ~ m_x = 123, m_y = 你好
BB的show ~ m_b = 哈哈, m_bx = 666
模板函数show ~ t = 嘻嘻嘻
AA ~ m_x = 123, m_y = 你好
BB的show ~ m_b = 哈哈, m_bx = 666

将模板类用作参数

C++的类模板主要是为了解决数据结构的问题。线性表有:链表数组、和队列。以链表数组为例,为了支持任意类型数据,最好的方法就是用类模板来实现,代码如下:

#include <iostream>
using namespace std;template <class T, int len> // 实际上,链表没有长度的说法,但为了演示,假定有一个长度
class LinkList {
public:T* m_head; // 定义链表头节点指针int m_len = len; // 指定表长度// 链表常用操作void insert() {cout << "LinkList 插入操作" << endl;}void ddelete() {cout << "LinkList 删除操作" << endl;}void update() {cout << "LinkList 更新操作" << endl;}
};template <class T, int len>
class Array{
public:T* m_data;int m_len = len;void insert() {cout << "Array 插入操作" << endl;}void ddelete() {cout << "Array 删除操作" << endl;}void update() {cout << "Array 更新操作" << endl;}
};int main() {return 0;
}

模板的目的就是代码重用,既然链表和数组的逻辑结构是一样的,那就把它们改成模板类的形式。目前模板LinkListArray,是为了兼容各种各样的数据类型,解决的是物理结构问题。接下来把它们再次模板化,是从逻辑角度来考虑的。C++支持模板的模板,意思是把模板名当成一种特殊的数据类型。实例化对象的时候,可以用模板签名作为参数,传给模板。示例代码如下:

#include <iostream>
using namespace std;template <class T, int len> // 实际上,链表没有长度的说法,但为了演示,假定有一个长度
class LinkList {
public:T* m_head; // 定义链表头节点指针int m_len = len; // 指定表长度// 链表常用操作void insert() {cout << "LinkList 插入操作" << endl;}void ddelete() {cout << "LinkList 删除操作" << endl;}void update() {cout << "LinkList 更新操作" << endl;}
};template <class T, int len>
class Array{
public:T* m_data;int m_len = len;void insert() {cout << "Array 插入操作" << endl;}void ddelete() {cout << "Array 删除操作" << endl;}void update() {cout << "Array 更新操作" << endl;}
};// 线性表模板类:其中,tabletype 表示 线性表类型,datatype 表示 线性表数据类型,len 表示 长度
// tabletype 不是一个普通的参数,而是模板,意思是这个参数要填模板名。
// 填什么样的模板名呢?填有两个参数的类模板名。并且,要求类模板的第一个参数是通用类型,第二个是非通用类型。
// 此外,class可以用typename代替,只是class更直观。
// tabletype只是一个模板名,用T1创建对象时,还需要指定具体的数据类型。
// 常见的做法是:具体的数据类型用模板参数从外面传进来
template<template<class, int>class tabletype, class datatype, int len> // 模板参数列表
class LinearList{
public:tabletype<datatype, len> m_table; // 创建线性表对象void insert() {m_table.insert();}void ddelete() {m_table.ddelete();}void update() {m_table.update();}
};int main() {// 创建线性表对象,容器类型为链表,链表的数据类型为int,链表长度为20LinearList<LinkList, int, 20> a;a.insert();a.ddelete();a.update();LinearList<Array, string, 20> b;b.insert();b.ddelete();b.update();return 0;
}

运行结果如下:

LinkList 插入操作
LinkList 删除操作
LinkList 更新操作
Array 插入操作
Array 删除操作
Array 更新操作

感谢浏览,一起学习!

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

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

相关文章

Flink中并行度和slot的关系——任务和任务槽

一、任务槽&#xff08;task slots) Flink的每一个TaskManager是一个JVM进程&#xff0c;在其上可以运行多个线程&#xff08;任务task&#xff09;&#xff0c;那么每个线程可以拥有多少进程资源呢&#xff1f;任务槽就是这样一个概念&#xff0c;对taskManager上每个任务运行…

Android着色器SweepGradient渐变圆环,Kotlin

Android着色器SweepGradient渐变圆环&#xff0c;Kotlin import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.Path import android.graphics.SweepGradient import android…

QT---------GUI程序设计基础

代码UI化设计&#xff08;QT&#xff09; 实例功能概述 假设我们要创建一个简单的计算器应用程序。该应用程序具有以下功能&#xff1a; 包含数字按钮&#xff08;0-9&#xff09;、操作符按钮&#xff08;、-、*、/&#xff09;、等于按钮&#xff08;&#xff09;和清除按…

torch.nn.functional的用法

文章目录 介绍激活函数示例 损失函数示例 卷积操作示例 池化示例 归一化操作示例 Dropout示例 torch.nn.functional 与 torch.nn 的区别 介绍 torch.nn.functional 是 PyTorch 中的一个模块&#xff0c;提供了许多函数式的神经网络操作&#xff0c;包括激活函数、损失函数、卷…

关于Nginx

1.Nginx的配置 proxy_pass http: 当你需要将请求分发到多个后端服务器时&#xff0c;需要实现负载均衡功能&#xff0c;可以使用upstream指令定义一组服务器&#xff0c;并在proxy_pass中引用这个服务组名称。。如果不需要负载均衡&#xff0c;只需要将请求转发到单一的后端…

redis用途都有哪些

Redis&#xff0c;作为一个开源的高性能键值对数据库&#xff0c;其用途广泛且功能强大。 1. 缓存&#xff08;Caching&#xff09;&#xff1a; • Redis常被用作缓存层&#xff0c;存储那些频繁访问但不易改变的数据&#xff0c;如用户会话、商品详情等。 • 通过将这些数据存…

YOLOv9-0.1部分代码阅读笔记-train.py

train.py train.py 目录 train.py 1.所需的库和模块 2.def train(hyp, opt, device, callbacks): 3.def parse_opt(knownFalse): 4.def main(opt, callbacksCallbacks()): 5.def run(**kwargs): 6.if __name__ "__main__": 1.所需的库和模块 import …

Gemma2 2B 模型的model.safetensors.index.json文件解析

Gemma2 2B 模型的 model.safetensors.index.json 文件解析 在使用 Gemma2 2B 模型或其他大型预训练模型时&#xff0c;model.safetensors.index.json 文件起到了索引的作用&#xff0c;它帮助我们了解模型的结构、参数存储方式以及如何加载模型的具体权重。本博客将深入解析该…

【每日学点鸿蒙知识】人脸活体检测、NodeController刷新、自动关闭输入框、Row设置中间最大宽、WebView单例

1、HarmonyOS 人脸活体检测调用&#xff1f; H5调用应用侧方法可参考以下demo&#xff1a; index.ets Web()//注册方法.javaScriptProxy({object: this.testObj,name: "testObjName",methodList: ["getLocationTS"],controller: this.webController})cla…

JSON结构快捷转XML结构API集成指南

JSON结构快捷转XML结构API集成指南 引言 在当今的软件开发世界中&#xff0c;数据交换格式的选择对于系统的互操作性和效率至关重要。JSON&#xff08;JavaScript Object Notation&#xff09;和XML&#xff08;eXtensible Markup Language&#xff09;是两种广泛使用的数据表…

期权懂|期权入门知识:开通50ETF期权需要什么条件?

锦鲤三三每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 开通50ETF期权需要什么条件&#xff1f; 一、基本资格要求 &#xff08;1&#xff09;年龄限制&#xff1a;投资者必须年满18周岁&#xff0c;具备完全民事行为能力。 &#…

实景三维点云处理专业软件ArcGIS根据DSM生成地表点云集

常见的实景三维处理软件及其特色功能如下&#xff1a; 一、专业实景三维建模软件 Agisoft Metashape 高精度建模&#xff1a;能够生成高精度的三维模型&#xff0c;精度可以达到厘米级甚至毫米级&#xff0c;适用于需要详细测量和分析的项目&#xff0c;如文物保护和建筑测量。…

实战指南:Shiro、CAS打造完美单点登录体验

引言 想象一下&#xff0c;在日常工作中&#xff0c;我们经常需要进行系统认证和授权。当用户尝试登录一个网站时&#xff0c;他们需要提供用户名和密码&#xff0c;网站会检查这些信息&#xff0c;确认用户是谁。这就是认证的过程。 一旦用户被认证&#xff0c;他们可能会尝…

阿里云大模型ACP高级工程师认证模拟试题

阿里云大模型ACP高级工程师认证模拟试题 0. 引言1. 模拟试题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题单选题单选题多选题多选题单选题多选题单…

cuda-cuDnn

cuda sudo /bin/sh cuda_11.7.0_515.43.04_linux.run cudnn cuDNN Archive | NVIDIA Developer Linux 系统 CUDA 多版本共存以及切换 – 颢天 安装cuda # 如果已经安装过驱动&#xff0c;驱动不需要再安装&#xff0c;取消勾选 安装cuDNN&#xff0c;cuda-cuDNN对应关系见…

QComboBox中使用树形控件进行选择

事情是这样的&#xff0c;要在一个ComboBox中通过树形结构进行内容的选择。 默认的QComboBox展开是下拉的列表。因此需要定制一下。 效果就是这样的 实现上面效果的核心代码就是下面这样的 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { treenew…

Error: The Calculated NPWS= 84330 != The Read NPWS= 84328

Tutorials — VASPKIT 1.5 documentation 设置PRECN 或者降低截断能 To aviod the error ’ERROR! Computed NPLANE **** ! input NPLANE ****’, please set PRECN or a medium/lower value of energy cuttoff.

【网络协议】路由信息协议 (RIP)

未经许可&#xff0c;不得转载。 路由信息协议&#xff08;Routing Information Protocol&#xff0c;简称 RIP&#xff09;是一种使用跳数&#xff08;hop count&#xff09;作为路由度量标准的路由协议&#xff0c;用于确定源网络和目标网络之间的最佳路径。 文章目录 什么是…

LoRA微调系列笔记

系列文章目录 第一章&#xff1a;LoRA微调系列笔记 第二章&#xff1a;Llama系列关键知识总结 第三章&#xff1a;LLaVA模型讲解与总结 文章目录 系列文章目录LoRA&#xff1a;Low-Rank Adaptation of Large Language Models目的&#xff1a;依据&#xff1a;优势&#xff1a;…

在K8S中,节点状态哪个组件负责上报?

在Kubernetes中&#xff0c;节点状态是kubelet组件负责定期上报的。Kubelet是运行在每个节点上的代理程序&#xff0c;它与Kubernetes Master节点上的控制面板组件紧密协作&#xff0c;以确保节点上的Pod能够正确运行。 kubelet的主要职责之一就是&#xff1a;与Kubernetes API…