(六)C++的函数模板与类模板

在C++中,模板(Templates)是一种强大的泛型编程工具,它允许程序员编写可重用的代码,而无需为每种数据类型编写重复的代码。模板分为函数模板(Function Templates)和类模板(Class Templates),它们分别用于生成函数和类的通用版本。以下是对函数模板和类模板的详细介绍,包括其定义、语法、实现方式、示例以及注意事项。

一.函数模板

函数模板是定义一组函数的蓝图或公式,这些函数在逻辑上执行相同的操作,但可以处理不同类型的数据。编译器根据函数调用时提供的参数类型,自动生成相应的函数实例。

语法

template <typename T>
ReturnType functionName(parameters) {// 函数实现
}template <typename T>:声明一个模板参数T,typename也可以用class代替。
ReturnType:函数的返回类型,可以依赖于模板参数T。
functionName:函数名称。
parameters:函数参数,可以是类型T或依赖于T的类型。

实现方式
函数模板通过编译器在编译时根据调用参数的类型生成具体的函数实例。

示例:

#include <iostream>
#include <string>// 函数模板定义
template <typename T>
T add(T a, T b) {return a + b;
}int main() {int sum1 = add(3, 4); // T 被推导为 intdouble sum2 = add(2.5, 3.6); // T 被推导为 doublestd::string sum3 = add(std::string("Hello, "), std::string("World!")); // T 被推导为 std::stringstd::cout << "Sum1: " << sum1 << std::endl; // 输出: Sum1: 7std::cout << "Sum2: " << sum2 << std::endl; // 输出: Sum2: 6.1std::cout << "Sum3: " << sum3 << std::endl; // 输出: Sum3: Hello, World!return 0;
}

注意事项
类型推导:编译器根据函数调用时的参数类型自动推导模板参数类型。
显式指定类型:可以使用显式指定类型的方式调用函数模板,例如:add(3, 4)。
多个模板参数:函数模板可以有多个模板参数

template <typename T, typename U>
void print(T a, U b) {std::cout << a << ", " << b << std::endl;
}

二.类模板(Class Templates)

类模板是定义一组类的蓝图或公式,这些类在逻辑上具有相同的结构,但可以处理不同类型的数据。编译器根据类实例化时提供的类型参数,自动生成相应的类实例。

语法

template <typename T>
class ClassName {// 类成员
};template <typename T>:声明一个模板参数T,typename也可以用class代替。
ClassName:类的名称。
类成员:类的成员变量和成员函数可以依赖于模板参数T。

实现方式
类模板通过编译器在编译时根据实例化时提供的类型参数生成具体的类实例

示例:

#include <iostream>
#include <vector>
#include <stdexcept>// 类模板定义
template <typename T>
class Stack {
private:std::vector<T> elements;
public:void push(const T& elem) {elements.push_back(elem);}void pop() {if(elements.empty()) {throw std::out_of_range("Stack<>::pop(): empty stack");}elements.pop_back();}T top() const {if(elements.empty()) {throw std::out_of_range("Stack<>::top(): empty stack");}return elements.back();}bool empty() const {return elements.empty();}
};int main() {Stack<int> intStack;intStack.push(10);intStack.push(20);std::cout << "Top element: " << intStack.top() << std::endl; // 输出: Top element: 20Stack<std::string> stringStack;stringStack.push("Hello");stringStack.push("World");std::cout << "Top element: " << stringStack.top() << std::endl; // 输出: Top element: Worldreturn 0;
}

注意事项
类型参数:类模板可以有多个类型参数

template <typename T, typename U>
class Pair {
private:T first;U second;
public:Pair(T f, U s) : first(f), second(s) {}void display() const {std::cout << first << ", " << second << std::endl;}
};

默认模板参数:C++11及更高版本支持为模板参数提供默认值:

template <typename T = int>
class MyClass {// ...
};

模板的优势
代码重用:通过模板,可以编写通用的代码,减少重复,提高代码的可维护性。
类型安全:模板在编译时进行类型检查,确保类型安全。
灵活性:模板可以处理不同类型的数据,提供高度的灵活性。

三.String类

在C++中,String类用于处理字符串操作。虽然C++标准库提供了强大的std::string类,但在某些情况下,程序员可能需要自定义一个String类,以满足特定的需求或用于学习目的。以下是对自定义String类的详细介绍,包括其定义、成员函数、运算符重载、内存管理以及与std::string的比较。

自定义String类通常是一个封装了C风格字符串(char*)的类,提供对字符串的各种操作接口。通过封装,可以更好地管理字符串的生命周期,避免内存泄漏和悬挂指针等问题。

基本实现

#include <iostream>
#include <cstring>class String {
private:char* data; // 指向字符串的指针
public:// 默认构造函数String() : data(new char[1]) {data[0] = '\0';}// 带参数的构造函数String(const char* str) {if(str) {data = new char[strlen(str) + 1];strcpy(data, str);}else {data = new char[1];data[0] = '\0';}}// 复制构造函数(深拷贝)String(const String& other) {data = new char[strlen(other.data) + 1];strcpy(data, other.data);}// 赋值运算符重载(深拷贝)String& operator=(const String& other) {if(this == &other)return *this;delete[] data;data = new char[strlen(other.data) + 1];strcpy(data, other.data);return *this;}// 析构函数~String() {delete[] data;}// 获取字符串长度size_t length() const {return strlen(data);}// 打印字符串void display() const {std::cout << data << std::endl;}// 字符串连接String operator+(const String& other) const {size_t len1 = strlen(data);size_t len2 = strlen(other.data);char* temp = new char[len1 + len2 + 1];strcpy(temp, data);strcat(temp, other.data);String result(temp);delete[] temp;return result;}// 获取C风格字符串const char* c_str() const {return data;}
};

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

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

相关文章

前端实现 GIF 图片循环播放

前言 使用 img 加载 GIF 图片&#xff0c;内容只会播放一次&#xff0c;之后就会自动暂停&#xff1b; 通过定时器在一段时间后重新加载图片的方式&#xff0c;会导致浏览器内存不断增大&#xff0c;并且可能会有闪烁、卡顿的问题&#xff1b; ImageDecoder WebCodecs API 的…

1-2 面向对象编程方法

1.0 面向对象编程思维 在面向对象风格中&#xff0c;结构体被看做数据&#xff08;data&#xff09;&#xff0c;而操作数据的函数称作方法&#xff08;method&#xff09;。目前函数 和数据是分离的&#xff0c;函数并不直接操作数据&#xff0c;我们需要拿到函数返回的结果&a…

LVGL4种输入设备详解(触摸、键盘、实体按键、编码器)

lvgl有触摸、键盘、实体按键、编码器四种输入设备 先来分析一下这四种输入设备有什么区别 &#xff08;1&#xff09;LV_INDEV_TYPE_POINTER 主要用于触摸屏 用到哪个输入设备保留哪个其他的也是&#xff0c;保留触摸屏输入的任务注册&#xff0c;其它几种种输入任务的注册&…

让文物“活”起来,以3D数字化技术传承文物历史文化!

文物&#xff0c;作为不可再生的宝贵资源&#xff0c;其任何毁损都是无法逆转的损失。然而&#xff0c;当前文物保护与修复领域仍大量依赖传统技术&#xff0c;同时&#xff0c;文物管理机构和专业团队的力量相对薄弱&#xff0c;亟需引入数字化管理手段以应对挑战。 积木易搭…

如何通过 ESPN API 获取 NBA 球队的赛程表

对于 NBA 爱好者和开发者来说&#xff0c;通过 API 获取球队赛程表是一项非常实用的功能&#xff0c;尤其是如果你正在构建一个应用或网站&#xff0c;需要自动化获取比赛安排的情况下。今天&#xff0c;我将为大家介绍如何通过 ESPN 提供的 API 获取 NBA 球队的赛程表。 1. ES…

LM Studio 部署本地大语言模型

一、下载安装 1.搜索&#xff1a;lm studio LM Studio - Discover, download, and run local LLMs 2.下载 3.安装 4.更改成中文 二、下载模型(软件内下载) 1.选择使用代理&#xff0c;否则无法下载 2.更改模型下载目录 默认下载位置 C:\Users\用户名\.lmstudio\models 3.搜…

【开源免费】基于SpringBoot+Vue.JS智能学习平台系统(JAVA毕业设计)

本文项目编号 T 181 &#xff0c;文末自助获取源码 \color{red}{T181&#xff0c;文末自助获取源码} T181&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

【R语言】环境空间

一、环境空间的特点 环境空间是一种特殊类型的变量&#xff0c;它可以像其它变量一样被分配和操作&#xff0c;还可以以参数的形式传递给函数。 R语言中环境空间具有如下3个特点&#xff1a; 1、对象名称唯一性 此特点指的是在不同的环境空间中可以有同名的变量出现&#x…

黑马 Linux零基础快速入门到精通 笔记

初识Linux Linux简介 提及操作系统&#xff0c;我们可能最先想到的是windows和mac&#xff0c;这两者都属于个人桌面操作系统领域&#xff0c;而Linux则属于服务器操作系统领域。无论是后端软件、大数据系统、网页服务等等都需要运行在Linux操作系统上。 Linux是一个开源的操作…

Golang:精通sync/atomic 包的Atomic 操作

在本指南中&#xff0c;我们将探索sync/atomic包的细节&#xff0c;展示如何编写更安全、更高效的并发代码。无论你是经验丰富的Gopher还是刚刚起步&#xff0c;你都会发现有价值的见解来提升Go编程技能。让我们一起开启原子运算的力量吧&#xff01; 理解Go中的原子操作 在快…

网络安全ITP是什么 网络安全产品ips

DS/IPS都是专门针对计算机病毒和黑客入侵而设计的网络安全设备 1、含义不同 IDS &#xff1a;入侵检测系统&#xff08;发现非法入侵只能报警不能自己过滤&#xff09; 做一个形象的比喻&#xff1a;假如防火墙是一幢大楼的门锁&#xff0c;那么IDS就是这幢大楼里的监视系统…

高速网络的未来:零拷贝Zero-Copy架构

在当今高速发展的信息技术领域&#xff0c;追求极致的性能和效率是永恒的主题。而当我们深入探索计算机系统的内部奥秘时&#xff0c;一个令人瞩目的概念 —— 零拷贝&#xff08;Zero-Copy&#xff09;架构&#xff0c;逐渐走入我们的视野。想象一下&#xff0c;在数据如洪流般…

备忘录模式

引言 当我们和朋友下棋的时候&#xff0c;我们很多情况下会发现下了一步臭棋&#xff0c;这时候就会和朋友开玩笑要悔棋&#xff0c;即撤回刚刚下的一步棋。在程序中&#xff0c;很多时候也会出错&#xff0c;我们也希望程序可以恢复出错前的状态&#xff0c;这就需要备忘录模式…

Element UI 表单源码原理

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

使用deepseek快速创作ppt

目录 1.在DeekSeek生成PPT脚本2.打开Kimi3.最终效果 DeepSeek作为目前最强大模型&#xff0c;其推理能力炸裂&#xff0c;但是DeepSeek官方没有提供生成PPT功能&#xff0c;如果让DeepSeek做PPT呢&#xff1f; 有个途径&#xff1a;在DeepSeek让其深度思考做出PPT脚本&#xf…

深入理解小波变换:信号处理的强大工具

引言 在科学与工程领域&#xff0c;信号处理一直是关键环节&#xff0c;傅里叶变换与小波变换作为重要的分析工具&#xff0c;在其中发挥着重要作用。本文将深入探讨小波变换&#xff0c;阐述其原理、优势以及与傅里叶变换的对比&#xff0c;并通过具体案例展示其应用价值。 一…

Kafka 入门与实战

一、Kafka 基础 1.1 创建topic kafka-topics.bat --bootstrap-server localhost:9092 --topic test --create 1.2 查看消费者偏移量位置 kafka-consumer-groups.bat --bootstrap-server localhost:9092 --describe --group test 1.3 消息的生产与发送 #生产者 kafka-cons…

WPS如何接入DeepSeek(通过第三方工具)

WPS如何接入DeepSeek 一、下载并安装OfficeAI插件二、配置OfficeAI插件三、使用DeepSeek功能 本文介绍如何通过 WPS 的第三方工具调用 DeepSeek 大模型&#xff0c;实现自动化文本扩写、校对和翻译等功能。 一、下载并安装OfficeAI插件 1、访问OfficeAI插件下载地址&#xff…

Day 32 卡玛笔记

这是基于代码随想录的每日打卡 455. 分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff…

[渗透测试]热门搜索引擎推荐— — shodan篇

[渗透测试]热门搜索引擎推荐— — shodan篇 免责声明&#xff1a;本文仅用于分享渗透测试工具&#xff0c;大家使用时&#xff0c;一定需要遵守相关法律法规。 除了shodan&#xff0c;还有很多其他热门的&#xff0c;比如&#xff1a;fofa、奇安信的鹰图、钟馗之眼等&#xff0…