C++模板类原理讲解
C++模板类原理讲解
C++模板是一种强大的编译期工具,它允许我们创建通用的、类型无关的类和函数。模板的主要目的是实现代码的重用和泛型编程。模板类的原理涉及以下几个方面:
- 模板的定义和实例化
- 模板的类型参数
- 模板特化
- 模板的编译过程
- 模板的优点和缺点
1. 模板的定义和实例化
模板是C++中用于创建泛型类和函数的机制。模板定义包含在关键字 template
后面的尖括号 < >
中,里面可以包含类型参数或非类型参数。
模板类定义示例:
template <typename T>
class GenericContainer {
private:T value;
public:GenericContainer(T value) : value(value) {}T getValue() const { return value; }void setValue(T value) { this->value = value; }void printValue() const { std::cout << "Value: " << value << std::endl; }
};
在上面的例子中,GenericContainer
是一个模板类,它可以接受任何类型 T
。
模板实例化:
模板在使用时会被实例化。例如:
GenericContainer<int> intContainer(42);
GenericContainer<std::string> stringContainer("Hello, Templates!");
这里,GenericContainer<int>
和 GenericContainer<std::string>
分别实例化了 GenericContainer
模板类,生成了具体的类定义。
2. 模板的类型参数
模板参数可以是类型参数(如 typename T
或 class T
),也可以是非类型参数(如 int N
)。
类型参数示例:
template <typename T>
class GenericContainer {// ...
};
非类型参数示例:
template <typename T, int Size>
class Array {
private:T data[Size];
public:int getSize() const { return Size; }
};
3. 模板特化
模板特化是指为特定类型或值提供特定的实现。分为完全特化和部分特化。
完全特化示例:
template <>
class GenericContainer<std::string> {
private:std::string value;
public:GenericContainer(std::string value) : value(value) {}std::string getValue() const { return value; }void setValue(std::string value) { this->value = value; }void printValue() const { std::cout << "String Value: " << value << std::endl; }
};
4. 模板的编译过程
模板是在编译期处理的,这意味着模板代码在使用时会被实例化并生成具体的类或函数定义。这种编译期处理带来了灵活性和性能优势,但也增加了编译时间和代码膨胀的风险。
编译器在遇到模板定义时不会立即生成代码,而是在模板被实际使用(实例化)时生成具体的代码。这被称为“惰性实例化”。
5. 模板的优点和缺点
优点:
- 代码重用:模板允许编写一次代码,可以用于多种类型。
- 类型安全:模板在编译时进行类型检查,减少了运行时错误。
- 性能:模板在编译时实例化,生成的代码通常不会有运行时的开销。
缺点:
- 编译时间:模板的实例化会增加编译时间。
- 代码膨胀:大量的模板实例化可能导致二进制文件变大。
- 错误信息复杂:模板错误信息通常比较复杂,难以调试。
示例代码讲解
GenericContainer.h
#ifndef GENERICCONTAINER_H
#define GENERICCONTAINER_H#include <iostream>
#include <string>template <typename T>
class GenericContainer {
private:T value;
public:GenericContainer(T value) : value(value) {}T getValue() const { return value; }void setValue(T value) { this->value = value; }void printValue() const { std::cout << "Value: " << value << std::endl; }
};template <>
class GenericContainer<std::string> {
private:std::string value;
public:GenericContainer(std::string value) : value(value) {}std::string getValue() const { return value; }void setValue(std::string value) { this->value = value; }void printValue() const { std::cout << "String Value: " << value << std::endl; }
};#endif // GENERICCONTAINER_H
Collection.h
#ifndef COLLECTION_H
#define COLLECTION_H#include <vector>
#include <iostream>template <typename T>
class Collection {
private:std::vector<T> elements;
public:void addElement(T element) { elements.push_back(element); }void printElements() const {for (const auto& element : elements) {std::cout << element << std::endl;}}template <typename U>bool contains(const U& value) const {for (const auto& element : elements) {if (element == value) {return true;}}return false;}
};#endif // COLLECTION_H
main.cpp
#include "GenericContainer.h"
#include "Collection.h"int main() {GenericContainer<int> intContainer(42);intContainer.printValue();GenericContainer<std::string> stringContainer("Hello, Templates!");stringContainer.printValue();Collection<int> intCollection;intCollection.addElement(1);intCollection.addElement(2);intCollection.addElement(3);intCollection.printElements();std::cout << "Contains 2? " << intCollection.contains(2) << std::endl;std::cout << "Contains 4? " << intCollection.contains(4) << std::endl;Collection<std::string> stringCollection;stringCollection.addElement("Hello");stringCollection.addElement("World");stringCollection.printElements();std::cout << "Contains 'Hello'? " << stringCollection.contains(std::string("Hello")) << std::endl;std::cout << "Contains 'C++'? " << stringCollection.contains(std::string("C++")) << std::endl;return 0;
}
总结
C++模板类提供了一种强大的机制,用于编写类型无关和高度可复用的代码。理解模板的定义、实例化、特化以及编译过程,对于高效使用C++模板至关重要。虽然模板带来了许多优点,但也伴随着一些缺点,如编译时间增加和代码膨胀。通过合理的设计和使用,可以充分发挥模板的优势,减少其不足。
源代码
相关文章:
C++模板类原理讲解
C模板类原理讲解 C模板是一种强大的编译期工具,它允许我们创建通用的、类型无关的类和函数。模板的主要目的是实现代码的重用和泛型编程。模板类的原理涉及以下几个方面: 模板的定义和实例化模板的类型参数模板特化模板的编译过程模板的优点和缺点 1.…...
scratch编程03-反弹球
这篇文章和上一篇文章《scratch3编程02-使用克隆来编写小游戏》类似(已经完全掌握了克隆的可以忽略这篇文章),两篇文章都使用到了克隆来编写一个小游戏,这篇文章与上篇文章不同的是,本体在进行克隆操作时,不…...
postgresql数据库进阶知识
postgresql数据库进阶知识 # 如果表存在就先删除 drop table if exists student; # 创建学生表 # id serial not null 表示id自增 # id integer not null 表示id不自增 create table student (id serial not nullconstraint student_pkprimary…...
关于HTTP劫持,该如何理解、防范和应对
一、引言 HTTP劫持(HTTP Hijacking)是一种网络安全威胁,它发生在HTTP通信过程中,攻击者试图通过拦截、篡改或监控用户与服务器之间的数据流量,以达到窃取敏感信息或执行恶意操作的目的。今天我们就来详细了解HTTP劫持…...
System.Data.OracleClient.OracleException:“ORA-12571: TNS: 包写入程序失败
System.Data.OracleClient.OracleException:“ORA-12571: TNS: 包写入程序失败 解决方法: 首先%oracle_home%/network/admin下的sqlnet.ora文件,把SQLNET.AUTHENTICATION_SERVICES (NTS)加个 # 注释掉就好了...
saas产品运营案例 | 联盟营销计划如何帮助企业提高销售额?
在当今数字化时代,SaaS(软件即服务)产品已成为企业提高效率、降低成本的重要工具。然而,面对激烈的市场竞争,如何有效地推广SaaS产品、提高销售额,成为许多企业面临的挑战。林叔将以ClickFunnels为例&#…...
模式分解算法-满足3NF的无损且保持函数依赖的分解算法、满足BCNF的无损连接分解算法
一、引言 1、对指定的关系模式,若范式级别较低,为第一范式或第二范式,由于存在数据冗余或更新异常问题,在实际中一般是不可用的,关系模式的规范化就是将满足低一级的关系模式分解为若干满足高一级范式的关系模式的集合…...
荷兰与法国战平,双方能携手出现?
就在昨天晚上,荷兰队经历了90分钟的鏖战,最终0-0与法国队握手言和。此役,哈维-西蒙斯为荷兰队打进一球,但进球被判无效。从目前的积分形势来看,双方基本上确定携手晋级16强赛。本场比赛,荷兰队后卫内森-阿克…...
数据可视化实验二:回归分析、判别分析与聚类分析
目录 一、使用回归分析方法分析某病毒是否与温度呈线性关系 1.1 代码实现 1.2 线性回归结果 1.3 相关系数验证 二、使用判别分析方法预测某病毒在一定的温度下是否可以存活,分别使用三种判别方法,包括Fish判别、贝叶斯判别、LDA 2.1 数据集展示&am…...
FL论文专栏|设备异构、异步联邦
论文:Asynchronous Federated Optimization(12th Annual Workshop on Optimization for Machine Learning) 链接 实现Server的异步更新。每次Server广播全局Model的时候附带一个时间戳,Client跑完之后上传将时间戳和Model同时带回…...
【Java毕业设计】基于JavaWeb的礼服租赁系统
文章目录 摘 要Abstract目录1 绪论1.1 课题背景和意义1.2 国内外研究现状1.2.1 国外研究现状 1.3 课题主要内容 2 开发相关技术介绍2.1 Spring Boot框架2.2 Vue框架2.3 MySQL数据库2.4 Redis数据库 3 系统分析3.1 需求分析3.1.1 用户需求分析3.1.2 功能需求分析 3.2 可行性分析…...
代码随想录训练营Day 66|卡码网101.孤岛的总面积、102.沉没孤岛、103.水流问题、104.建造最大岛屿
1.孤岛的总面积 101. 孤岛的总面积 | 代码随想录 代码:(bfs广搜) #include <iostream> #include <vector> #include <queue> using namespace std; int dir[4][2] {1,0,0,1,-1,0,0,-1}; int count; void bfs(vector<vector<int>>&a…...
根据状态转移写状态机-二段式
目录 描述 输入描述: 输出描述: 描述 题目描述: 如图所示为两种状态机中的一种,请根据状态转移图写出代码,状态转移线上的0/0等表示的意思是过程中data/flag的值。 要求: 1、 必须使用对应类型的状…...
PyTorch C++扩展用于AMD GPU
PyTorch C Extension on AMD GPU — ROCm Blogs 本文演示了如何使用PyTorch C扩展,并通过示例讨论了它相对于常规PyTorch模块的优势。实验在AMD GPU和ROCm 5.7.0软件上进行。有关支持的GPU和操作系统的更多信息,请参阅系统要求(Linux…...
Hadoop archive
Index of /dist/hadoop/commonhttps://archive.apache.org/dist/hadoop/common/...
R语言——R语言基础
1、用repeat、for、while计算从1-10的所有整数的平方和 2、编写一个函数,给出两个正整数,计算他们的最小公倍数 3、编写一个函数,让用户输入姓名、年龄,得出他明年的年龄。用paste打印出来。例如:"Hi xiaoming …...
VFB电压反馈和CFB电流反馈运算放大器(运放)选择指南
VFB电压反馈和CFB电流反馈运算放大器(运放)选择指南 电流反馈和电压反馈具有不同的应用优势。在很多应用中,CFB和VFB的差异并不明显。当今的许多高速CFB和VFB放大器在性能上不相上下,但各有其优缺点。本指南将考察与这两种拓扑结构相关的重要考虑因素。…...
elasticsearch安装(centos7)
先给出网址 elasticsearch:Download Elasticsearch | Elastic elasticKibana:Download Kibana Free | Get Started Now | Elastic Logstash:Download Logstash Free | Get Started Now | Elastic ik分词:Releases infinilabs/…...
Java高手的30k之路|面试宝典|精通JVM(二)
JVM基本结构 类加载子系统:负责将.class文件加载到内存中,并进行验证、准备、解析和初始化。运行时数据区:包括堆(Heap)、方法区(Method Area)、Java栈(Java Stack)、本…...
JVM专题六:JVM的内存模型
前面我们通过Java是如何编译、JVM的类加载机制、JVM类加载器与双亲委派机制等内容了解到了如何从我们编写的一个.Java 文件最终加载到JVM里的,今天我们就来剖析一下这个Java的‘中介平台’JVM里面到底长成啥样。 JVM的内存区域划分 Java虚拟机(JVM&…...
学习java第一百零七天
解释JDBC抽象和DAO模块 使用JDBC抽象和DAO模块,我们可以确保保持数据库代码的整洁和简单,并避免数据库资源关闭而导致的问题。它在多个数据库服务器给出的异常之上提供了一层统一的异常。它还利用Spring的AOP模块为Spring应用程序中的对象提供事务管理服…...
k8s上尝试滚动更新和回滚
滚动更新和回滚 实验目标: 学习如何进行应用的滚动更新和回滚操作。 实验步骤: 创建一个 Deployment。更新 Deployment 的镜像版本,观察滚动更新过程。回滚到之前的版本,验证回滚操作。 今天呢,我们继续来进行我们k…...
GitHub Copilot 登录账号激活,已经在IntellJ IDEA使用
GitHub Copilot 想必大家都是熟悉的,一款AI代码辅助神器,相信对编程界的诸位并不陌生。 今日特此分享一项便捷的工具,助您轻松激活GitHub Copilot,尽享智能编码之便利! GitHub Copilot 是由 GitHub 和 OpenAI 共同开…...
进程知识点(二)
文章目录 一、进程关系?二、孤儿态进程(Orphan)定义危害处理 三、僵尸进程定义处理 四、守护进程(Daemon )定义作用 总结 一、进程关系? 亲缘关系:亲缘关系主要体现于父子进程,子进程父进程创建,代码继承于父进程&…...
【线性代数】【一】1.6 矩阵的可逆性与线性方程组的解
文章目录 前言一、求解逆矩阵二、线性方程组的解的存在性总结 前言 前文我们引入了逆矩阵的概念,紧接着我们就需要讨论一个矩阵逆的存在性以及如何求解这个逆矩阵。最后再回归上最初的线性方程组的解,分析其中的联系。 一、求解逆矩阵 我们先回想一下在…...
基于大型语言模型的全双工语音对话方案
摘要解读 我们提出了一种能够以全双工方式运行的生成性对话系统,实现了无缝互动。该系统基于一个精心调整的大型语言模型(LLM),使其能够感知模块、运动功能模块以及一个具有两种状态(称为神经有限状态机,n…...
Spring Boot集成Minio插件快速入门
1 Minio介绍 MinIO 是一个基于 Apache License v2.0 开源协议的对象存储服务。它兼容亚马逊 S3 云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小&…...
【C++新特性】右值引用
右值和右值的区别 C11 中右值可以分为两种:一个是将亡值( xvalue, expiring value),另一个则是纯右值( prvalue, PureRvalue): 纯右值:非引用返回的临时变量、运算表达式产生的临时变…...
信息安全基础知识(完整)
信息安全基础知识 安全策略表达模型是一种对安全需求与安全策略的抽象概念表达,一般分为自主访问控制模型(HRU)和强制访问控制模型(BLP、Biba)IDS基本原理是通过分析网络行为(访问方式、访问量、与历史访问…...
QT
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) ,Gcancle(new QPushButton("取消",this)) ,EmmEdit(new QLineEdit(this)) { ui->setupUi(this);…...
公司建设网站算入什么会计科目/云南网站建设百度
免费邮箱容量太小不适合办公,邮件刚破千就提示邮箱容量已满,有没有什么好办法可以解决这个问题呢?当然有的呀,今天就告诉大家邮箱容量满了如何解决?如何注册超大容量个人邮箱 邮箱容量满了如何解决? 我们…...
中国最好的网站器域名统一/搜索指数分析
为了更好的阅读体验,可以前往语雀 查看原文G2 是一个基于图形语法,面向数据分析的统计图表引擎。G2Plot 是在 G2 基础上,屏蔽复杂概念的前提下,保留 G2 强大图形能力,封装出业务上常用的统计图表库。G2Plot 是一个基于…...
小皮搭建本地网站/seo搜索优化 指数
vue.js react是仅仅几年前,我们通过小心谨慎地将每个标签可爱地放置在文件中来构建我们的网站吗? 手工制作网站的时代已经过去。 大多数现代网站都是精心制作的程序,它们会不断地对多个数据源执行ping操作,然后搅乱嵌套在其他标签…...
郑州的网站建设/关键词搜索方法
1.Comparable 接口的定义:public interface Comparable{public int compareTo(T o)}接口中只有一个 compareTo 方法,该方法返回一个 int 类型的数据,但是 int 的值只能是3种:*1:表示大于*-1:表示小于*0&…...
做有色研究的网站/浏览器网页版入口
利用Excel 测试函数 AND OR 以及ELSE IF的用法Javascript里面的三元表达式 var a 1, b 2; if (a b 4) {alert(wly);//如果表达式成立 } else {alert("dh");//如果表达式不成立 }1,AND 函数 90分以上的科目 成绩2的成绩不能低于30分,并且成…...
郑州大学现代远程教育 《网页设计与网站建设》个人主页/短视频seo软件
近期开发工程的感触很深,发现通过这几年来我构建自己的知识体系趋于完善的同时出现的分支,这个类似树。深刻理解古代智慧和自然哲学原理。 从无序中寻找有序,这是我对图像的一句总描述。前段时间由于一个项目初步计划和赵博晚上聊了一下&…...