C++从入门到实战(十三)C++函数模板与类模板初阶讲解
C++从入门到实战(十三)C++函数模板与类模板初阶讲解
- 前言
- 一、为什么需要模板
- 1. 函数重载的问题
- 2. 泛型编程和模板的作用
- 二、函数模板
- 2.1 函数模板格式
- 2.2 函数模板的原理
- 2.3 函数模板的实例化
- (1)隐式实例化:
- (2)显式实例化:
- 2.4 模板参数的匹配原则
- 1. 非模板函数与同名函数模板共存
- 2. 调用时的优先选择规则
- 3. 类型转换规则差异
- 三、类模板
- 3.1 类模板是什么?
- 3.2 类模板的定义格式
- 3.3 类模板的实例化:从 “模具” 生成具体类
- 3.4 类模板的注意事项
- 1.模板参数声明不能省略
- 2. 声明和定义不能分离到.h 和.cpp
- 3. 支持多个模板参数
前言
- 在上一篇博客中,我们围绕 C/C++ 内存管理展开讨论,深入解析了内存分布模型、C 与 C++ 内存管理的核心差异,并初步认识了 C++ 中new与delete的基本用法,为理解 C++ 内存管理体系打下基础。
- 从本文开始,我们将暂别内存管理主题,转而聚焦 C++ 模板编程的核心模块 ——函数模板初阶
我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482
一、为什么需要模板
1. 函数重载的问题
在C++里,要是你想实现交换两个变量值的功能,对不同类型的变量(像int
、double
、char
),就得写不同的Swap
函数。
- 就像下面这样:
void Swap(int& left, int& right){int temp = left;left = right;right = temp;}void Swap(double& left, double& right){double temp = left;left = right;right = temp;}void Swap(char& left, char& right){char temp = left;left = right;right = temp;}
不过,这种函数重载的做法存在一些弊端:
- 代码复用率低:这些重载函数只是处理的变量类型不同,代码的逻辑是一样的。要是以后有新的类型,就得手动再写对应的
Swap
函数。 - 可维护性差:如果其中一个
Swap
函数出了问题,可能所有重载函数都得检查一遍,因为它们的代码逻辑本质相同,一处出错可能其他地方也有类似问题。
2. 泛型编程和模板的作用
为了解决上面的问题,C++引入了泛型编程的概念。
- 泛型编程的目标是编写和具体类型无关的通用代码,以此实现代码复用。而模板就是泛型编程的基础。
可以把模板想象成一个模具。当你需要不同类型的具体代码时,就往这个模具里填入不同的“材料”(也就是类型),这样就能得到不同“材料”的“铸件”(也就是具体类型的代码)。
比如,使用模板来实现Swap
函数:
现在看一下,后面我们会详细讲解
template <typename T>
void Swap(T& left, T& right) {T temp = left;left = right;right = temp;
}
这里的template <typename T>
就声明了一个模板,T
是一个类型参数,它代表任意类型。在使用这个Swap
函数时,编译器会根据传入的变量类型,自动用具体类型替换T
,生成对应的代码。这样就不用为每种类型都写一个单独的函数,既提高了代码复用率,也让代码更易于维护。
二、函数模板
- 函数模板就像是一个函数家族,它和具体的类型没关系。在使用的时候,会根据传入的实参类型,生成特定类型的函数版本。
2.1 函数模板格式
函数模板的定义格式是:template<typename T1, typename T2,......,typename Tn>
,后面接着返回值类型、函数名和参数列表。
- 比如Swap函数模板:
template<typename T>
void Swap( T& left, T& right)
{T temp = left;left = right;right = temp;
}
这里的typename是用来定义模板参数的关键字,也能用class,但不能用struct代替class
#include <iostream>
using namespace std;template<typename T>
void Swap( T& left, T& right)
{T temp = left;left = right;right = temp;
}
int main() {int a = 5, b = 10;cout << "Before swap: a = " << a << ", b = " << b << endl;Swap(a, b); // 调用模板函数,传入int类型的参数cout << "After swap: a = " << a << ", b = " << b << endl;return 0;
}
2.2 函数模板的原理
-
函数模板就像一个蓝图,它本身不是真正的函数,而是让编译器根据使用方式生成特定类型函数的模具。
-
这样就把原本我们要做的重复工作交给了编译器。
-
在编译阶段,编译器会根据传入的实参类型,推演出对应的类型,然后生成专门处理该类型的代码。
-
例如用double类型使用模板时,编译器会把T确定为double类型,生成处理double类型的代码
2.3 函数模板的实例化
- 用不同类型的参数使用函数模板,就叫做函数模板的实例化。
- 分为隐式实例化和显式实例化。
(1)隐式实例化:
让编译器根据实参来推导出模板参数的实际类型。比如Add函数模板:
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
#include <iostream>
using namespace std;template<class T>
T Add(const T& left, const T& right)
{return left + right;
}int main()
{int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;cout << Add(a1, a2) << endl;cout << Add(d1, d2) << endl;
}
- 当我们写成这样时
int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;Add(a1, d1);
- 编译器会报错,因为编译器无法确定T是int还是double
- 处理方式:需要自己强制转换
- 在模板里,编译器一般不会进行类型转换,怕出问题。
(2)显式实例化:
在函数名后的<>里指定模板参数的实际类型。
- 比如:
int main(void)
{int a = 10;double b = 20.0;// 显式实例化Add<int>(a, b);return 0;
}
如果类型不匹配,编译器会尝试隐式类型转换,转换不成功就会报错
#include <iostream>
using namespace std;template<class T>
T Add(const T& left, const T& right)
{return left + right;
}int main(void)
{int a = 10;double b = 20.0;// 显式实例化cout << Add<int>(a, b) << endl;return 0;
}
2.4 模板参数的匹配原则
1. 非模板函数与同名函数模板共存
- 在 C++ 里,一个非模板函数和同名的函数模板能够同时存在。
- 而且函数模板可以实例化为与非模板函数相同功能的函数。
#include <iostream>// 专门处理 int 类型的加法非模板函数
int Add(int left, int right) {return left + right;
}// 通用加法函数模板
template<class T>
T Add(T left, T right) {return left + right;
}int main() {// 调用 Add(1, 2),会和非模板函数匹配std::cout << "调用 Add(1, 2) 的结果: " << Add(1, 2) << std::endl;// 调用 Add<int>(1, 2),会调用编译器特化的 Add 版本std::cout << "调用 Add<int>(1, 2) 的结果: " << Add<int>(1, 2) << std::endl;return 0;
}
在上述代码中,定义了一个专门处理 int
类型的非模板 Add
函数,以及一个通用的 Add
函数模板。
- 当调用
Add(1, 2)
时,由于实参类型是int
,编译器会优先选择非模板函数。而调用Add<int>(1, 2)
时,明确指定了使用函数模板,编译器会对模板进行实例化,生成处理int
类型的函数。
2. 调用时的优先选择规则
当非模板函数和同名函数模板其他条件相同时,调用时会优先选择非模板函数。
- 不过,要是模板能产生更匹配的函数,就会选择模板。下面通过代码来进一步说明:
#include <iostream>// 专门处理 int 类型的加法非模板函数
int Add(int left, int right) {return left + right;
}// 通用加法函数模板,可处理不同类型的参数
template<class T1, class T2>
auto Add(T1 left, T2 right) {return left + right;
}int main() {// 调用 Add(1, 2),和非模板函数完全匹配std::cout << "调用 Add(1, 2) 的结果: " << Add(1, 2) << std::endl;// 调用 Add(1, 2.0),模板函数能生成更匹配的版本std::cout << "调用 Add(1, 2.0) 的结果: " << Add(1, 2.0) << std::endl;return 0;
}
在这段代码中,调用 Add(1, 2)
时,实参类型都是 int
,与非模板函数完全匹配,所以会调用非模板函数。
- 而调用
Add(1, 2.0)
时,实参类型分别是int
和double
,非模板函数无法直接匹配,此时模板函数能生成更匹配的版本,编译器就会选择模板函数进行实例化并调用。
3. 类型转换规则差异
模板函数不允许自动类型转换,而普通函数可以进行自动类型转换。
#include <iostream>// 普通加法函数
int Add(int left, int right) {return left + right;
}// 函数模板
template<class T>
T Add(T left, T right) {return left + right;
}int main() {int a = 1;double b = 2.0;// 普通函数可以进行自动类型转换std::cout << "普通函数调用 Add(a, b) 的结果: " << Add(a, b) << std::endl;// 模板函数不允许自动类型转换,下面这行代码会报错// std::cout << "模板函数调用 Add(a, b) 的结果: " << Add(a, b) << std::endl;// 若要使用模板函数,需手动进行类型转换std::cout << "模板函数调用 Add(a, static_cast<int>(b)) 的结果: " << Add(a, static_cast<int>(b)) << std::endl;return 0;
}
在上述代码中,调用普通函数 Add(a, b)
时,编译器会自动将 double
类型的 b
转换为 int
类型。
- 而调用模板函数
Add(a, b)
时,由于模板函数不允许自动类型转换,会导致编译错误。若要使用模板函数,需要手动进行类型转换,如Add(a, static_cast<int>(b))
。
三、类模板
3.1 类模板是什么?
-
想象你要做一个 “栈”(Stack)类,用来存储数据。
-
如果数据可能是整数、小数、字符等不同类型,难道要为每种类型写一个独立的Stack类吗?
-
类模板就是解决这个问题的 “通用模具”:它定义一个与类型无关的类,通过传入具体类型,生成针对该类型的专属类。
3.2 类模板的定义格式
template <class T1, class T2, ..., class Tn> // 模板参数列表,T是类型占位符
class 类模板名 {// 类的成员(变量/函数)可以使用T1、T2等模板参数// 例如:成员变量类型是T,成员函数参数类型是T&
};
#include <iostream>
using namespace std;template <typename T> // 等价于template <class T>,T代表任意类型
class Stack {
public:// 构造函数:初始化数组和容量Stack(size_t capacity = 4) {_array = new T[capacity]; // 数组元素类型是T_capacity = capacity;_size = 0;}// 声明成员函数(参数类型是T&)void Push(const T& data); // 向栈中添加数据private:T* _array; // 存储数据的数组,类型是T*size_t _capacity; // 容量size_t _size; // 已存储元素数量
};// 类外定义成员函数时,需要再次指定模板参数
template <class T> // 必须重复模板参数声明
void Stack<T>::Push(const T& data) { // 用Stack<T>表明这是T类型的成员函数if (_size < _capacity) {_array[_size] = data; // 存入数据,类型是T_size++;}
}
3.3 类模板的实例化:从 “模具” 生成具体类
类模板本身不是真正的类,必须通过实例化指定具体类型,才能生成可用的类。
- 语法:
类模板名<具体类型> 对象名;
- 显式指定类型:必须在类名后用<>明确写出类型(不能像函数模板那样隐式推导)。
- 生成专属类:每个不同的类型实例化,都会生成一个独立的类。
例如上面代码中的
int main() {Stack<int> st1; // 实例化出存储int的栈类,生成Stack<int>类Stack<double> st2; // 实例化出存储double的栈类,生成Stack<double>类st1.Push(10); // 向int栈中添加数据st2.Push(3.14); // 向double栈中添加数据return 0;
}
- Stack是模板名,不是类型;Stack才是具体的类型(就像 “模具压出的产品”)。
- 每个实例化的类(如
Stack<int>、Stack<double>
)都是独立的,互不干扰。
3.4 类模板的注意事项
1.模板参数声明不能省略
- 在类外定义成员函数时,必须像
template <class T>
一样重复声明模板参数,否则编译器不知道T是什么。
2. 声明和定义不能分离到.h 和.cpp
- 模板需要在编译阶段根据实例化的类型生成代码,如果声明在.h、定义在.cpp,编译器可能找不到定义,导致链接错误。
3. 支持多个模板参数
- 可以定义多个类型参数,例如:
template <class T, class U> // 两个类型参数T和U
class Pair {T first;U second;
};
Pair<int, double> p(10, 3.14); // 实例化时传入两个类型
以上就是这篇博客的全部内容,下一篇我们将继续探索C++中STL更多精彩内容。
我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482
非常感谢您的阅读,喜欢的话记得三连哦 |
相关文章:
C++从入门到实战(十三)C++函数模板与类模板初阶讲解
C从入门到实战(十三)C函数模板与类模板初阶讲解 前言一、为什么需要模板1. 函数重载的问题2. 泛型编程和模板的作用 二、函数模板2.1 函数模板格式2.2 函数模板的原理2.3 函数模板的实例化(1)隐式实例化:(2…...
CentOS服务器中如何解决内存泄漏问题?
内存泄漏并不是“爆炸性内存飙升”,而是程序申请了内存但没有释放,造成系统可用内存逐渐减少,直到用光。 表现形式: 系统空闲内存越来越少;swap频繁被占用;某些服务响应变慢甚至挂掉;重启服务后内存才释放。 内存泄漏的根源在哪…...
【Java项目脚手架系列】第三篇:Spring MVC基础项目脚手架
【Java项目脚手架系列】第三篇:Spring MVC基础项目脚手架 前言 在前面的文章中,我们介绍了Maven基础项目脚手架和JavaWeb基础项目脚手架。今天,我们将介绍Spring MVC项目脚手架,这是一个用于快速搭建Web应用的框架。 什么是Spr…...
chili3d调试笔记12 deepwiki viewport svg雪碧图 camera three.ts
xiangechen/chili3d | DeepWiki viewport阅读 🧠deep 我要把模型投影成dxf导出有什么办法 引用lookat 截图是如何实现的 明天接着搞 ---------------------------------------------------------------- 截图没什么用 搞个工程图模块可能才行 一个文件一行 忘…...
tinyrenderer笔记(Shader)
tinyrenderer个人代码仓库:tinyrenderer个人练习代码 前言 现在我们将所有的渲染代码都放在了 main.cpp 中,然而在 OpenGL 渲染管线中,渲染的核心逻辑是位于 shader 中的,下面是 OpenGL 的渲染管线: 蓝色是我们可以自…...
【奔跑吧!Linux 内核(第二版)】第1章:Linux 系统基础知识
笨叔 陈悦. 奔跑吧 Linux 内核(第2版) [M]. 北京: 人民邮电出版社, 2020. 文章目录 Linux 系统的发展历史Linux 发行版Red Hat LinuxDebian LinuxSuSE Linux优麒麟 Linux Linux 内核介绍宏内核和微内核Linux 内核概貌 Linux 系统的发展历史 Linux 系统诞…...
Spring + Shiro 整合的核心要点及详细实现说明
在 Spring 项目中集成 Apache Shiro 可以实现轻量级的安全控制(认证、授权、会话管理等)。以下是 Spring Shiro 整合的核心要点及详细实现说明: 一、Spring 与 Shiro 整合的核心组件 组件作用ShiroFilterFactoryBean创建 Shiro 过…...
已经写好论文的AI率降低
视频演示 https://www.bilibili.com/video/BV1v4VpzgEdc 提示词 你是我专门请来的“降维写作助手”,专门干一件事:把 AI 写得太“像 AI”的文字改得更像人写的。我们主要是处理论文、创作类内容,目标就是:不让检测工具一眼识破…...
AI教你学VUE——Deepseek版
一、基础阶段:打好Web开发基础 HTML/CSS基础 学习HTML标签语义化、CSS布局(Flex/Grid)、响应式设计(媒体查询、REM/VW单位)。资源推荐: MDN Web文档(免费):HTML | CSS实战…...
卷积神经网络基础(五)
6.3 Softmax-with-Loss 层 我们最后介绍输出层的softmax函数,之前我们知道softmax函数会将输入值正规化之后再输出。在手写数字识别的例子中,softmax层的输出如下: 输入图像通过Affi ne层和ReLU层进行转换,10个输入通过Softmax层…...
Go语言——string、数组、切片以及map
一、string、数组、切片代码 package mainimport "fmt"// 定义结构体 type student struct {id intname stringage intscore float32 }func main() {// 使用var声明切片var slice1 []intslice1 append(slice1, 1)slice1 append(slice1, 2)slice1 append(sl…...
线性回归有截距
In [ ]: ∑ i 1 m ( y i − x i T w ) 2 \sum _{i1}^{m}(y_{i}-x_{i}^{T}w)^{2} i1∑m(yi−xiTw)2 w ^ ( X T X ) − 1 X T y \hat {w}(X^{T}X)^{-1}X^{T}y w^(XTX)−1XTy In [ ]: 1 #如果有截距,求解时,需要梯度下降法求解w 和b …...
【基础】Python包管理工具uv使用全教程
一、uv简介 uv 是由 Astral(前身为 Basis)团队开发的 Python 包安装器和解析器,完全使用 Rust 语言编写。与传统 Python 工具不同,uv 将多个工具的功能整合到一个高性能的解决方案中,旨在提供更现代、更高效的 Python…...
事务(transaction)-上
事务概述 食物是一个最小的工作单元。在数据库当中,事务表示一件完整的事儿。一个业务的完成可能需要多条DML语句共同配合才能完成,例如转账业务,需要执行两条DML语句,先更新张三账户的余额,再更新李四账户的余额&…...
Python训练打卡Day17
无监督算法中的聚类 知识点 聚类的指标聚类常见算法:kmeans聚类、dbscan聚类、层次聚类三种算法对应的流程 实际在论文中聚类的策略不一定是针对所有特征,可以针对其中几个可以解释的特征进行聚类,得到聚类后的类别,这样后续进行解…...
【爬虫】码上爬第6题-倚天剑
堆栈入手: 全部复制的话,注意修改一些必要在地方: 通过s函数来获取请求头的加密参数 通过xxxxoooo来获取解密后的数据 js代码关键点: python代码我推荐使用这个网站: Convert curl commands to code 根据生成的代码…...
自定义SpringBoot Starter-笔记
SpringBoot Starter的介绍参考: Spring Boot Starter简介-笔记-CSDN博客。这里介绍如何自定义一个springBoot Starter。 1. 项目结构 创建一个 Maven 项目,结构如下: custom-spring-boot-starter-demo/ ├── custom-hello-jdk/ # jdk模…...
一周学会Pandas2 Python数据处理与分析-Pandas2数据类型转换操作
锋哥原创的Pandas2 Python数据处理与分析 视频教程: 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili Pandas 提供了灵活的方法来处理数据类型转换,以下是常见操作及代码示例: 1. 查看数据类型 …...
Java中常见的问题
1. SSO中的Cookie/Token生成与安全传递 生成Cookie/Token: Cookie:服务器通过Set-Cookie响应头生成,包含用户ID、过期时间等,需设置HttpOnly和Secure属性防止XSS和中间人攻击。Token(如JWT):使…...
【JEECG】BasicTable内嵌Table表格错位
功能说明: 解决代码生成后,本地内嵌Table表格样式错位。 优化前: 优化后: 解决方法: 对应的List.vue页面增加css样式调整。 <style lang"less" scoped>//内嵌表格margin边距覆盖:deep(.ant-table-…...
人工智能 计算智能模糊逻辑讲解
引言 在计算智能(Computational Intelligence)领域,模糊逻辑(Fuzzy Logic)作为一种处理不确定性与模糊性信息的数学工具,自 1965 年由洛夫特扎德(Lotfi Zadeh)提出以来,…...
基于SSM实现的健身房系统功能实现一
一、前言介绍: 1.1 项目摘要 随着社会的快速发展和人们健康意识的不断提升,健身行业也在迅速扩展。越来越多的人加入到健身行列,健身房的数量也在不断增加。这种趋势使得健身房的管理变得越来越复杂,传统的手工或部分自动化的管…...
spring详解-循环依赖的解决
Spring循环依赖 重点提示: 本文都快写完了,发现“丈夫” 的英文是husband… 在“②有AOP循环依赖” 改过来了,前面用到的位置太多了就没改。我是说怎么idea的hansband英文下面怎么有波浪线。各位能够理解意思就行,英文拼写不要过…...
【大模型面试每日一题】Day 10:混合精度训练如何加速大模型训练?可能出现什么问题?如何解决?
【大模型面试每日一题】Day 10:混合精度训练如何加速大模型训练?可能出现什么问题?如何解决? 📌 题目重现 🌟🌟 面试官:混合精度训练如何加速大模型训练?可能出现什么问…...
[学习]RTKLib详解:rtkcmn.c与rtkpos.c
文章目录 Part A、Rrtkcmn.c一、总体功能二、关键API列表三、核心算法实现四、函数功能与参数说明1. uniqnav2. lsq3. filter4. matmul5. satazel6. ionmapf7. geodist8. timeadd9. dgetrf_ / dgetri_(LAPACK接口) 五、工作流程说明4.1 模块在RTKLib中的…...
cookie/session的关系
什么是cookie,session 我们平时去医院看病时,从进医院那一刻,我们最开始要做的就是挂号(需要我们填写表格,记录一些核心信息,医生会把这些信息录入电脑,并给我办一个就诊卡,卡里面只…...
Linux(十四)进程间通信(IPC),管道
一、进程间通信 (一)系统介绍进程间通信 进程间通信(IPC)介绍 小编插入的这篇文章详细介绍了进程间通信的一些内容,大家可以一起学习。 (二)进程间通信的方法 1、管道 2、信号量 3、共享…...
Nmap 工具的详细使用教程
Nmap(Network Mapper)是一款开源且功能强大的网络扫描和安全审计工具。它被广泛用于网络发现、端口扫描、操作系统检测、服务版本探测以及漏洞扫描等。 官方链接: Nmap 官方网站: https://nmap.org/Nmap 官方文档 (英文): https://nmap.org/book/man.h…...
Vue 自定义指令输入校验过滤
/*** 过滤字符串* param {*} filterCharRule* param {*} newVal* returns*/ function filterCharForValue(filterCharRule, newVal) {if(!filterCharRule || !newVal) returnconst isArray filterCharRule instanceof Arrayconst isRegExp filterCharRule instanceof RegExpi…...
OpenGl实战笔记(2)基于qt5.15.2+mingw64+opengl实现纹理贴图
一、作用原理 1、作用:将一张图片(纹理)映射到几何体表面,提升视觉真实感,不增加几何复杂度。 2、原理:加载图片为纹理 → 上传到 GPU;为顶点设置纹理坐标(如 0~1 范围)&…...
tinyrenderer笔记(透视矫正)
tinyrenderer个人代码仓库:tinyrenderer个人练习代码 引言 还要从上一节知识说起,在上一节中我为了调试代码,换了一个很简单的正方形 obj 模型,配上纹理贴图与法线贴图进行渲染,得了下面的结果: what&…...
c++类【发展】
类的静态成员(用static声明的成员),在声明之外用例单独的语句进行初始化,初始化时,不再需要用static进行限定。在方法文件中初始化。以防重复。 特殊成员函数 复制构造函数: 当使用一个对象来初始化另一个对象…...
玛格丽特鸡尾酒评鉴,玛格丽特酒的寓意和象征
玛格丽特鸡尾酒会有独特的风味,而且还会有一个比较吸引人的背后故事。在目前的鸡尾酒界就会占据着很重要的地位,不仅是味蕾的盛宴,同样也会拥有深厚的情感。 玛格丽特由龙舌兰酒、柠檬汁和君度橙酒调制而成,将三者巧妙地结合在一起…...
关于Java多态简单讲解
面向对象程序设计有三大特征,分别是封装,继承和多态。 这三大特性相辅相成,可以使程序员更容易用编程语言描述现实对象。 其中多态 多态是方法的多态,是通过子类通过对父类的重写,实现不同子类对同一方法有不同的实现…...
SecureCrt设置显示区域横列数
1. Logical rows //逻辑行调显示区域高度的 一般超过50就全屏了 2. Logical columns //逻辑列调显示区域宽度的 3. Scrollback buffer //缓冲区大小...
【PhysUnits】1 SI Prefixes 实现解析(prefix.rs)
一、源码 // prefix.rs //! SI Prefixes (国际单位制词头) //! //! 提供所有标准SI词头用于单位转换,仅处理10的幂次 //! //! Provides all standard SI prefixes for unit conversion, handling only powers of 10.use typenum::{Z0, P1, P2, P3, P6, P9, P12, …...
【Python】--实现多进程
import multiprocessing import time # 1.定义好函数 # codeing def coding():for i in range(10):print(f正在编写第{i}行代码)time.sleep(0.2)# music def music():for i in range(10):print(f正在听第{i}首歌曲)time.sleep(0.2)单任务 # 单任务--时间为4s多 if __name__ _…...
计算机视觉与深度学习 | 基于数字图像处理的裂缝检测与识别系统(matlab代码)
🍅🍅🍅🍅🍅🍅🍅🍅🍅🍅🍅🍅🍅🍅🍅🍅 基于数字图像处理的裂缝检测与识别系统 🥦🥦🥦🥦🥦🥦🥦🥦🥦🥦🥦🥦🥦**系统架构设计****1. 图像预处理**目标:消除噪声+增强裂缝特征**2. 图像分割**目标:提取裂缝区域**3. 特征…...
嵌入式MCU语音识别算法及实现方案
在嵌入式MCU(微控制器单元)中实现语音识别,由于资源限制(如处理能力、内存、功耗等),通常需要轻量级算法和优化技术。以下是常见的语音识别算法及实现方案: 一、传统语音识别算法 动态时间规整&…...
【C++核心技术深度解析:从继承多态到STL容器 】
一、C继承机制:代码复用与层次设计 1. 继承基础概念 什么是继承? 继承是面向对象编程的核心机制,通过class Derived : public Base让子类(派生类)复用父类(基类)的属性和方法,同时…...
【C/C++】new关键字解析
📘 C 中 new 关键字详解笔记 🔹 什么是 new? new 是 C 中用于动态内存分配的关键字,它在堆内存中为对象或变量分配空间,并返回对应类型的指针。 与 C 语言中的 malloc 相比,new 更安全、更方便ÿ…...
C++高性能内存池
目录 1. 项目介绍 1. 这个项目做的是什么? 2. 该项目要求的知识储备 2. 什么是内存池 1. 池化技术 2. 内存池 3. 内存池主要解决的问题 4.malloc 3. 先设计一个定长的内存池 4.高并发内存池 -- 整体框架设计 5. 高并发内存池 -- thread cache 6. 高并发内存池 -- …...
chili3d调试笔记12 deepwiki viewport
xiangechen/chili3d | DeepWiki viewport阅读 🧠deep 我要把模型投影成dxf导出有什么办法 引用lookat 截图是如何实现的 明天接着搞 ----------------------------------------------------------------...
前端取经路——JavaScript修炼:悟空的九大心法
大家好,我是老十三,一名前端开发工程师。JavaScript如同孙悟空的七十二变,变化多端却又充满威力。本篇文章我将带你攻克JS中最令人头疼的九大难题,从闭包陷阱到原型链继承,从异步编程到性能优化。每个难题都配有实战代…...
从零实战:在Xilinx Zynq PS端移植VxWorks 6.9系统
一、环境准备与工具链搭建 1.1 硬件配置清单 开发板: Zynq-7000系列(推荐ZedBoard或ZCU102)调试工具: USB-JTAG调试器(如Xilinx Platform Cable USB II)存储介质: SD卡(建议Class 10以上)1.2 软件环境 工具版本作用Vivado2022.1FPGA硬件设计Vitis2022.1系统集成开发Wind…...
网工实验——RIP配置
网络拓扑图 配置 1.为每台设备配置ip地址 AR4 <Huawei>u t m <Huawei>sys [Huawei]sysname AR4 [AR4]int g0/0/0 [AR4-GigabitEthernet0/0/0]ip address 172.16.1.1 24 [AR4-GigabitEthernet0/0/0]q#下面配置换回口,模拟网 [AR4]int LoopBack 0 [AR4…...
前端流行框架Vue3教程:14. 组件传递Props效验
(4) 组件传递Props效验 Vue组件可以更细致地声明对传入的props的校验要求 ComponentA.vue <script> import ComponentB from ./ComponentB.vue; export default {components: {ComponentB},data() {return {title: 标题}} } </script> <template><h3&g…...
电子电器架构 --- 网关ECU中采用多CPU解决方案来实现网关功能
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...
关于tftpboot的用法
TFTPBOOT 是一个常用于嵌入式系统或网络设备中的命令,用于通过 TFTP 协议从网络上启动操作系统镜像或引导文件。这个命令通常在设备启动时执行,允许设备通过网络从 TFTP 服务器下载启动镜像或其他必要的文件,而不需要从本地存储中启动。 一般…...
团队协作的润滑剂——GitHub与协作流程
各位代码界的社交恐惧症患者们,今天我们要聊的是如何假装自己很会团队协作——使用GitHub!这就像程序员版的"相亲平台",只不过在这里,你展示的不是自拍和收入,而是代码和commit记录(后者往往更令…...