c++初阶------c++代码模块

作者前言

🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂
​🎂 作者介绍: 🎂🎂
🎂 🎉🎉🎉🎉🎉🎉🎉 🎂
🎂作者id:老秦包你会, 🎂
简单介绍:🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂
喜欢学习C语言、C++和python等编程语言,是一位爱分享的博主,有兴趣的小可爱可以来互讨 🎂🎂🎂🎂🎂🎂🎂🎂
🎂个人主页::小小页面🎂
🎂gitee页面:秦大大🎂
🎂🎂🎂🎂🎂🎂🎂🎂
🎂 一个爱分享的小博主 欢迎小可爱们前来借鉴🎂


代码模型

  • **作者前言**
  • 泛型编程
    • 函数模板
      • 函数模板的实例化
      • 隐式实例化
      • 显示实例化
    • 类模板
    • 类的实例化(区别普通类和模板类的类型)
    • 类模板声明和定义分离
  • 普通函数和函数模板

泛型编程

前面我们学习了c++的函数重载,知道一个函数名可以相同,但是形参的类型或者个数不能相同,如果我们要通过操作不同类型的数据可以进行函数重载,但是很不方便。
进行函数重载,效率也很低下,每次出现新的类型,就要重载一次,
泛型编程的出现就是为了解决这些问题而生的

函数模板

函数模板格式:
template<typename T1, typename T2,…,typename Tn>
返回值类型 函数名(参数列表){}
注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)
模板参数和函数的参数很像,函数的参数定义的是形参,模板参数定义的是类型

#include<iostream>
using namespace std;

template<typename T1>
void Swa(T1& a, T1& b)
{
	T1 c = a;
	a = b;
	b = c;
}
int main()
{
	int a = 10, b = 30;
	double c = 1.0, d = 2.0;
	Swa(a, b);
	Swa(c, d);
	cout << "a=" << a << ",b=" << b << endl;
	cout << "c=" << c << ",d=" << d << endl;
	return 0;
}

不同类型调用的函数不是同一个的,
在这里插入图片描述
在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此

函数模板的实例化

不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化显式实例化。

隐式实例化

隐式实例化:让编译器根据实参推演模板参数的实际类型

#include<iostream>
using namespace std;

template<typename T1>
void Swa(T1& a, T1& b)
{
	T1 c = a;
	a = b;
	b = c;
}
int main()
{
	int a = 10, b = 30;
	double c = 1.0, d = 2.0;
	Swa(a, b);
	Swa(c, d);
	cout << "a=" << a << ",b=" << b << endl;
	cout << "c=" << c << ",d=" << d << endl;
	return 0;
}

如果函数模板参数只有一个,例如Swa(a,c),这个编译器就会报错,隐式实例化,也就是编译器看到我们传入但是参数进行推演,进行确定类型

显示实例化

#include<iostream>
using namespace std;
template<typename T>
T Add( T a,  T b)
{
  return a+b;
}
template<typename T1>
void print(T1& a)
{
  cout << a <<endl;
}
int main()
{
  int a = 1.0;
  double b = 2.0;
  cout<<Add(a,(int)b)<<endl;//少数用法
  cout <<Add<int>(3,3.8)<<endl;//显式实例化
  return 0;
}

格式:
函数名<类型>(参数列表)
这样可以模板参数只有一个,传参可以传不同的类型

模版参数的如果推不出类型就会报错,通常模版参数一般有几种使用场景
作为函数参数

template<typename T1>
void print(T1& a)
{
  cout << a <<endl;
}

我们只需要进行传参就可以知道T的类型,
使用显示实例化

template<typename T1>
void Sta(int n )
	{
		T1*_a = new T1[n];
		int _top = 0;
		int _capacity = n;
	}

如果我们要推出T1的类型就必须进行显示实例化,例如:
Sta(30)

类模板

#include<iostream>
using namespace std;
template<class T1>
class Stack
{
public:
	Stack(int n = 4)
	{
		_a = new T1[n];
		_top = 0;
		_capacity = n;
	}
	Stack(const Stack& a)
	{
		_top = a._top;
		_capacity = a._capacity;
		_a = new T1[_capacity];
	}
	~Stack()
	{
		delete[] _a;
		_top = 0;
		_capacity = 0;
	}
private:
	T1* _a;
	int _top;
	int _capacity;

};
int main()
{
	//显示实例化
	Stack<int> str1;
	Stack<char> str2;
	return 0;
}

模板格式

template<class T1, class T2, ..., class Tn>
class 类模板名
{
 // 类内成员定义
};

类的实例化(区别普通类和模板类的类型)

我们知道普通类,一旦定义了就是确定了类型,所以可以理解为普通类的类名就是类型
而类的模板的类名不是类型,我们需要显示实例化才能确定是类,

Stack<int>str1;
Stack<double>str2;

Stack是类型,
Stack 只是类名
在这里插入图片描述
可以看到模板类的类型就是这样的,普通类的类型就是类名

类模板声明和定义分离

#include<iostream>
using namespace std;
template<class T1>
class Stack
{
public:
	Stack(int n = 4);
	Stack(const Stack& a)
	{
		_top = a._top;
		_capacity = a._capacity;
		_a = new T1[_capacity];
	}
	~Stack()
	{
		cout << _capacity << endl;
		delete[] _a;
		_a = nullptr;
		_top = 0;
		_capacity = 0;
	}
private:
	T1* _a;
	int _top;
	int _capacity;

};
//定义
template<class T1>
Stack<T1>::Stack(int n)
{
	_a = new T1[n];
	_top = 0;
	_capacity = n;
}
int main()
{
	//显示实例化
	Stack<int> str1;
	Stack<char> str2;
	return 0;
}

注意:类模板声明和定义不支持分开到多个文件,只能在一个文件内

普通函数和函数模板

在模板函数和普通函数重载时,C++编译器对函数的调用规则如下:

当函数模板和普通函数都符合调用时,优先选择普通函数。如果想显示使用函数模板,则使用<>类型列表。
如果函数模板能产生更好的匹配,则使用函数模板。
函数模板不允许自动类型转化,普通函数能够进行自动类型转换(隐式类型转换)。

#include<iostream>
using namespace std;
template<typename T>
T Add(const T& a,const T& b)//这里是引用的是一个临时变量,具有常性,需要用const来接收
{
	return a + b;
}

int Add(int a, int b)
{
	return a + b;
}
int main()
{
	cout << Add(1, 2) <<endl;//调用的是普通函数
	cout<< Add<double>(2.1, 3.1) <<endl;//调用的也是普通函数

	return 0;
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

档案室升级改造基建方面需要考虑哪些问题

升级和改造档案室可能需要以下材料&#xff1a; 1. 墙壁和地板材料&#xff1a;选择耐用、易于清洁的材料&#xff0c;如瓷砖、大理石、地板、木材或维护低的地毯等。 2. 墙体材料&#xff1a;可能需要新的墙壁材料来分隔出更多的空间&#xff0c;例如石膏板、砖块或玻璃隔断等…

R语言神经网路模型应用(1)

数据集heart_learning.csv与heart_test.csv是关于心脏病的数据集&#xff0c;heart_learning.csv是训练数据集&#xff0c;heart_test.csv是测试数据集。要求&#xff1a;target和target2为因变量&#xff0c;其他诸变量为自变量&#xff0c;用神经网络模型&#xff08;多层感知…

javaWeb私人牙科诊所管理系统

一、摘要 随着科技的飞速发展&#xff0c;计算机已经广泛的应用于各个领域之中。在医学领域中&#xff0c;计算机主要应用于两个方面&#xff1a;一是医疗设备智能化&#xff0c;以硬件为主。另一种是病例信息管理系统&#xff08;HIS&#xff09;以软件建设为主&#xff0c;以…

MySQL 高级语句(一)

一、MySQL查询 1.1 排序 ASC 是按照升序进行排序的&#xff0c;是默认的排序方式&#xff0c;即可以省略&#xff1b; SELECT语句中如果没有指定具体的排序方式&#xff0c;则默认按ASC方式进行排序。 DESC是按降序方式进行排列。当然ORDER BY前面也可以使用 WHFRE 子句对查…

23.异步模式-生产者、消费者

1.与保护性暂停GuardedObject不同&#xff0c;不需要产生结果与消费结果的线程一一对应。 2.消费队列可以用来平衡生产和消费的线程资源。 3.生产者负责产生结果数据&#xff0c;不关心数据该如何处理&#xff0c;而消费者专心处理结果数据。 4.消息队列是有容量限制的&…

风险评估在网络安全领域的应用与实践

一、引言 在数字化浪潮席卷全球的今天&#xff0c;网络安全已成为企业运营和发展的核心问题。随着信息技术的快速发展&#xff0c;企业面临着日益复杂的网络安全威胁&#xff0c;如黑客攻击、数据泄露、恶意软件等。这些威胁不仅可能导致企业重要信息的丢失或泄露&#xff0c;…

2024 年 5 款适用于 Linux 的参考文献管理软件

时间是宝贵的&#xff0c;因此如果某款软件能让您摆脱必须执行的日常繁琐任务&#xff0c;那么它就会派上用场。 参考文献管理工具就是此类软件的典型代表&#xff0c;只需点击几下就能自动格式化引文。学生、教育工作者、作家、科学家和研究人员一定会发现它们非常有用。 在…

各城市宗族文化姓氏占比数据

各城市宗族文化姓氏占比数据 1、指标&#xff1a;省份代码、所属省份、城市代码、所属城市、第1大姓氏、第2大姓氏、第3大姓氏、宗族文化强度 2、方法说明&#xff1a; 根据2005年全国1%的人口调查数据计算。其中第1大姓氏第一大姓人口数/总人口数&#xff0c;宗族文化强度(…

华院计算荣获CSDN“创新企业”和“年度创新产品与解决方案”大奖

日前&#xff0c;全国最大的专业开发者社区CSDN发布“2023中国开发者影响力年度榜单”&#xff0c;华院计算凭借其卓越的认知智能引擎平台荣获“创新企业”和“年度创新产品与解决方案”两项大奖。 CSDN 以数据为基础&#xff0c;经过个人或企业提交资料、层层筛选、深入调研、…

详解:写作和赚钱的 4 个关系!看完你一定会忍不住想开始写!

飞书文档的加密很强&#xff0c;也没有和自家的豆包大模型融合&#xff0c;所以只能通过其他方式获取文档的内容。 &#xff08;1&#xff09;将飞书文档转换为PDF&#xff0c;要用到浏览器插件&#xff1a; GoFullPage - Full Page Screen Capture - Microsoft Edge Addons …

C#代码混淆器 ipaguard 的优势与使用

摘要 本文探讨了iOS开发的优势、费用以及软件开发方面的相关内容。通过分析iOS开发所采用的编程语言、开发环境、用户界面设计、应用审核流程以及应用领域等方面&#xff0c;展示了iOS开发的诸多优势和特点。虽然iOS开发具有高用户体验、统一的硬件和软件环境、良好的市场份额…

Java基础-网络编程

文章目录 1.网络相关概念1.网络通信2.网络3.IP地址4.域名和端口域名端口号 5.网络协议6.TCP和UDPTCP协议**UDP协议**TCP VS UDP 2.网络编程1.InetAddress1.基本介绍2.代码实例 2.Socket1.基本介绍 3.Tcp字节流编程1.客户端与服务器端的信息传输案例一代码实例案例二代码实例案例…

【前端面试3+1】02插槽、箭头函数与普通函数、重绘重排、【回文数】

一、对插槽的理解 1.定义及作用&#xff1a; 插槽是一种用于在组件中插入内容的特殊语法。它的作用是让父组件可以向子组件传递内容&#xff0c;从而实现组件的灵活性和复用性。 2.分类&#xff1a; 插槽可以分为具名插槽和作用域插槽。 2.1具名插槽&#xff1a; 具名插槽允许父…

RuoYi-Vue-Plus(sa-token)

一、介绍 官网&#xff1a; Sa-Tokenhttps://sa-token.cc/index.html 特性&#xff1a; 登录与权限认证&#xff1a;支持用户登录和细粒度权限认证。会话管理&#xff1a;提供会话创建、维护和销毁功能。单点登录&#xff1a;支持单点登录&#xff0c;简化多应用登录流程。OAu…

基于el-table实现行内增删改

实现效果&#xff1a; 核心代码&#xff1a; <el-table :data"items"style"width: 100%;margin-top: 16px"border:key"randomKey"><el-table-column label"计划名称"property"name"><template slot-scope&q…

雪里温柔,水边明秀,不及Java 抽象类 和 Object类

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

Linux环境基础开发工具使用——yum and vim

本篇将会介绍平时在Linux中开发常用到的一些工具&#xff0c;其中包括&#xff1a;软件包管理器 — yum&#xff0c;Liunx中的开发工具。具体的介绍了 yum 的相关操作以及 yum 源&#xff0c;同时还介绍了 windows与虚拟机如何进行的关联。然后对Liunx中的开发工具进行了详细的…

集合(下)Map集合的使用

文章目录 前言一、Map接口二、Map接口的实现类 1.HashMap类2.TreeMap类总结 前言 Map集合没有继承Collection接口&#xff0c;不能像List集合和Set集合那样直接使用Collection接口的方法。Map集合其自身通过以key到value的映射关系实现的集合&#xff0c;也有相应的许多方法。类…

超详细SpringMVC源码剖析

整体流程图 1.自定义视图(63~66) 视图解析过程 1.先到DispatcherServlet中央控制器, 根据视图解析的 优先级 执行对应的 视图解析器 Nullable protected View resolveViewName(String viewName, Nullable Map<String, Object> model,Locale locale, HttpServletReque…

【C语言】【Leetcode】70. 爬楼梯

文章目录 题目思路&#xff1a;简单递归 > 动态规划 题目 链接: link 思路&#xff1a;简单递归 > 动态规划 这题类似于斐波那契数列的算法&#xff0c;结果其实就是到达前一步和到达前两步的方法之和&#xff0c;一直递归到n1和n2时就行了&#xff0c;但是这种算法有个…