C++第七篇 模板初阶和STL简介

news2024/11/24 2:37:17


目录

一,模板初阶

1.泛型编程

2.函数模板

2.1 函数模板概念

2.2 函数模板格式

2.3 函数模板的原理

2.4 函数模板的实例化

2.5 模板参数的匹配原则

3.类模板(模板类,模板函数)

3.1 类模板定义格式

二,STL简介

1. 什么是STL

2. STL的版本

2.1 原始版本

2.2 P.J.版本

2.3 RW版本

2.4 SGI版本

3.STL的六大组件


一,模板初阶

1.泛型编程

编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础

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;
}

使用函数重载虽然可以实现,但是有一下几个不好的地方:
1. 重载的函数仅仅是类型不同,代码复用率比较低只要有新类型出现时,就需要用户自己增
加对应的函数。

2. 代码的可维护性比较低,一个出错可能所有的重载均出错 。


那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?

2.函数模板

2.1 函数模板概念

        函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

2.2 函数模板格式

template<typename T1, typenameT2,......,typenameTn>

返回值类型 函数名(参数列表){}

例子:

template <class T>
void Swap(const T& x,const T& y)
{
	T temp = x;
	x = y;
	y = temp;
}

typename是用来定义模板参数关键字,也可以使用class。

参数问题

当时只有一个class时,两个参数必须是同一类型

template <class T>
void Swap(const T& x,const T& y)
{
	T temp = x;
	x = y;
	y = temp;
}

int main()
{
	int x1 = 1;
	int x2 = 2;
	double y1 = 3.0;
	double y2 = 4.0;
	Swap(x1, x2);//对
	Swap(y1, y2);//对
	Swap(x1, y1);//错
}

如果想要交换两个不同类型就要写两个class

template <class T1,class T2>
void Swap(const T1& x,const T2& y)
{
	T1 temp = x;
	x = y;
	y = temp;
}
int main()
{
	int x1 = 1;
	int x2 = 2;
	double y1 = 3.0;
	double y2 = 4.0;
	Swap(x1, y1);
	cout << x1 << ' ' << y1 << endl;
}

2.3 函数模板的原理

函数模板是一个蓝图它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具
所以其实模板就是将本来应该我们做的重复的事情交给了编译器。

2.4 函数模板的实例化

用函数模板生成对应的函数,称为函数模板的实例化。模板参数实例化分为:隐式实例化
和显式实例化。

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

template <class T>
int Add(const T& x,const T& y)
{
	return x + y;
}
int main()
{
	int x1 = 1;
	int x2 = 2;
	double y1 = 3.0;
	double y2 = 4.0;

// 此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化
	Add(x1, (int)y1);
	cout << x1 << ' ' << y1 << endl;
}

(2).显式实例化

在函数名后的<>中指定模板参数的实际类型

template <class T>
int Add(const T& x,const T& y)
{
	return x + y;
}
int main()
{
	int x1 = 1;
	int x2 = 2;
	double y1 = 3.0;
	double y2 = 4.0;
	cout << Add<double>(x1, y1) << endl;
}

2.5 模板参数的匹配原则

(1). 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这
个非模板函数。

template <class T>
int Add(const T& x,const T& y)
{
	return x + y;
}

int Add(int a, int b)
{
	cout << "ADD: ";
	return (a + b);
}

int main()
{
	int x1 = 1;
	int x2 = 2;
	double y1 = 3.0;
	double y2 = 4.0;
	cout << Add(x1, y1) << endl;
}

运行结果:

(2). 对于非模板函数和同名函数模板,如果其他条件都相同在调动时会优先调用非模板函数。如果模板可以产生一个具有更好匹配的函数 那么将选择模板

int Add(int left, int right)
{
	cout << "Add1:";
	return left + right;
}
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{
	cout << "Add2:";
	return left + right;
}
void main()
{
	cout << Add(1, 2) << endl; // 与非函数模板类型完全匹配,不需要函数模板实例化
	cout << Add(1, 2.0) << endl; // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的
}

运行结果:

3.类模板(模板类,模板函数)

3.1 类模板定义格式

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

例如:

类模板实现栈

#include<iostream>
using namespace std;
template<typename T>
class Stack
{
public:

	Stack(int n = 4)
		:_array(new T[n])
		, _capacity(n)
		, _size(0)
	{}

	~Stack()
	{
		delete[] _array;
		_array = nullptr;
		_size = _capacity = 0;
	}

	void Push(const T& data)
	{
		if (_size == _capacity)
		{
			T temp = new T[_capacity * 2];
			memcpy(temp, _array, sizeof(T) * _size);

			_array = temp;
			_capacity = _capacity * 2;

		}
		_array[_size++] = data;
	}

private:
	T* _array;
	size_t _capacity; 
	size_t _size;
};

int main()
{
	Stack<int> st1; 
	Stack<double> st2;
	return 0;
}

当声明与定义分离时,要声明模板类

template<typename T>
class Stack
{
public:

	Stack(int n = 4)
		:_array(new T[n])
		, _capacity(n)
		, _size(0)
	{}

	~Stack()
	{
		delete[] _array;
		_array = nullptr;
		_size = _capacity = 0;
	}

	void Push(const T& data);
	

private:
	T* _array;
	size_t _capacity; 
	size_t _size;
};

template<typename T>
void Stack<T>::Push(const T& data)
{
	if (_size == _capacity)
	{
		T temp = new T[_capacity * 2];
		memcpy(temp, _array, sizeof(T) * _size);

		_array = temp;
		_capacity = _capacity * 2;

	}
	_array[_size++] = data;
}


二,STL简介

1. 什么是STL

STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包含数据结构与算法的软件框架。

2. STL的版本

2.1 原始版本

        Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。 HP 版本--所有STL实现版本的始祖。

2.2 P.J.版本

        由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,符号命名比较怪异。

2.3 RW版本

        由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。

2.4 SGI版本

        由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用可移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。我们学习STL主要参考的就是这个版本

3.STL的六大组件


本篇完

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

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

相关文章

【JUC】并发编程与源码分析 1-7章

1 线程基础知识复习 1把锁&#xff1a;synchronized&#xff08;后面细讲&#xff09; 2个并&#xff1a; 并发&#xff08;concurrent&#xff09;&#xff1a;是在同一实体上的多个事件&#xff0c;是在一台机器上“同时”处理多个任务&#xff0c;同一时刻&#xff0c;其…

【学习笔记】A2X通信的协议(三)- A2X PC5通信(一)

目录 6. A2X通信 6.1 A2X PC5通信 6.1.1 一般说明 6.1.2 通过NR-PC5的单播模式A2X通信 6.1.2.1 概述 6.1.2.2 A2X PC5单播链路建立程序 6.1.2.2.1 一般说明 6.1.2.2.2 发起UE启动A2X PC5单播链路建立程序 6.1.2.2.3 目标UE接受的A2X PC5单播链路建立程序 6.1.2.2.5 目…

学单片机怎么在3-5个月内找到工作?

每个初学者&#xff0c;都如履薄冰&#xff0c;10几年前&#xff0c;我自学单片机时&#xff0c;也一样。 想通过学习&#xff0c;找一份体面点的工作&#xff0c;又害怕辛辛苦苦学出来&#xff0c;找不到工作。 好在&#xff0c;当初执行力&#xff0c;还算可以&#xff0c;自…

WebLogic

二、WebLogic 2.1 后台弱口令GetShell 漏洞描述 通过弱口令进入后台界面&#xff0c;上传部署war包&#xff0c;getshell 影响范围 全版本(前提后台存在弱口令) 漏洞复现 默认账号密码:weblogic/Oracle123weblogic常用弱口令: Default Passwords | CIRT.net这里注意&am…

设计模式--结构型

类适配器 #include <queue> #include <iostream> #include <algorithm> #include <iterator>using namespace std;// 目标接口 class Target {public:virtual ~Target() {}virtual void method() 0; };// 适配者类 class Adaptee {public:void spec_…

CHIESI凯西医药:外企入职测评综合能力及性格测试SHL题库测评真题解析

CHIESI凯西医药是一家意大利国际制药集团&#xff0c;以研发为核心&#xff0c;专注于呼吸道健康、罕见疾病和专科治疗的创新治疗方案。集团总部位于意大利帕尔马市&#xff0c;拥有超过85年的历史&#xff0c;业务遍及全球31个国家和地区&#xff0c;拥有7,000多名员工。2023年…

day22(mysql数据库主从搭建)

上午&#xff1a; 1、为mysql添加开机启动chkconfig 2、编辑配置文件my.cnf 3、修改环境变量 4、mysql角色授权 角色不生效 在配置文件中不添加activate_all_roles_on_loginon glibc安装&#xff0c;my.cnf在项目目录之下 rpm安装&#xff0c;my.cnf文件在/etc/my.cnf 5、自…

函数实例讲解(五)

文章目录 提取字符串必学的函数&#xff08;LEFT、MID、RIGHT、LEN、LENB&#xff09;1、LEFT2、RIGHT3、MID4、LEN5、LENB 提取实战套路知多少1、FIND2、ISNUMBER 利用随机函数来抽奖&#xff08;RAND、RANDBETWEEN&#xff09;1、RAND2、RANDBETWEEN 排名的几种套路&#xff…

解决nacos疯狂报错“user nacos not found”

nacos疯狂报错“user nacos not found” 参考博客&#xff1a;https://blog.csdn.net/cnskylee/article/details/137640113 背景&#xff1a;项目启动后一直刷“user nacos not found”报错信息&#xff0c;但是不影响接口调用 解决&#xff1a; 1、将nacos版本切换为2.2.2&am…

ET实现游戏中聊天系统逻辑思路(服务端)

目录 一、准备工作 1.1 前言 1.2 完善聊天服务器 1.3 自定义聊天服消息 二、玩家登录聊天服 2.1 Gate网关与聊天服通讯 2.2 保存玩家实体映射实例ID 三、处理聊天逻辑 3.1 发送聊天消息的定义 3.2 定义聊天记录组件 3.3 编写发送聊天消息处理类 ET是一个游戏框架&…

Linux--shell脚本语言—/—终章

一、shell函数 1、shell函数定义格式 参数说明&#xff1a; 1、可以带function fun() 定义&#xff0c;也可以直接fun() 定义,不带任何参数。 2、参数返回&#xff0c;可以显示加&#xff1a;return 返回&#xff0c;如果不加&#xff0c;将以最后一条命令运行结果&#xff…

(20)SSM-MyBatis关系映射

MyBatis关联映射 概述 在实际开发的工程中&#xff0c;经常对出现多表操作&#xff0c;如果常见的根据某条数据的ID去检索数据&#xff08;根据用户查询订单信息&#xff09;&#xff0c;这个时候我们数据库设计的时候就需要使用外键进行关联&#xff0c;那么mybatis在操作这…

推荐4款2024年热门的win10 录屏软件。

如果只是偶尔需要简单地录制一下电脑屏幕&#xff0c;一般大家都会选免费且操作简单的软件&#xff1b;但如果是专业的视频制作&#xff0c;就需要功能强大、支持后期编辑的软件。而下面的这4款软件却能满足以上两种需求&#xff0c;并且能够兼容的系统也很多。 1、福昕专业录屏…

如何提升你的广告创意?

当你有一个好的产品时&#xff0c;你一定会想到用广告投放来推广它。但简单的广告投放是不足以帮助你建立起品牌知名度的。要从众多产品中脱颖而出&#xff0c;还需要独特又有效的广告创意。以下是尤里改为你总结的提升广告创意的办法&#xff0c;电子商务品牌可以着重了解下~ …

没有软件测试经验的计算机毕业生如何准备面试测试工程师这一职位?

古语云&#xff1a;“知己知彼&#xff0c;百战不殆”。 想应聘测试工程师&#xff0c;首先要知道企业需要什么样的测试工程师&#xff0c;需要具备哪些技术。想知道这点并不难&#xff0c;并且有捷径可走&#xff0c;直接去招聘网站中找答案&#xff0c;看各公司的招聘简章即…

opencascade TopoDS、TopoDS_Vertex、TopoDS_Edge、TopoDS_Wire、源码学习

前言 opencascade TopoDS转TopoDS_Vertex opencascade TopoDS转TopoDS_Edge opencascade TopoDS转TopoDS_Wire opencascade TopoDS转TopoDS_Face opencascade TopoDS转TopoDS_Shell opencascade TopoDS转TopoDS_Solid opencascade TopoDS转TopoDS_Compound 提供方法将 TopoDS_…

Pytorch损失函数-torch.nn.NLLLoss()

一、简介 1.1 nn.CrossEntropyLoss 交叉熵损失函数的定义如下&#xff1a; 就是我们预测的概率的对数与标签的乘积&#xff0c;当qk->1的时候&#xff0c;它的损失接近零。 1.2 nn.NLLLoss 官方文档中介绍称&#xff1a; nn.NLLLoss输入是一个对数概率向量和一个目标标…

进阶学习------线程等待

什么是线程等待 线程等待是指在一个多线程程序中&#xff0c;一个线程在继续执行之前需要等待另一个线程完成特定任务或达到某个状态的行为。在编程中&#xff0c;线程等待是一种同步机制&#xff0c;用于协调不同线程之间的执行顺序&#xff0c;确保数据的一致性和避免竞态条…

鸿蒙AI功能开发【拍照识别文字】

拍照识别文字 介绍 本示例通过使用ohos.multimedia.camera (相机管理)和textRecognition&#xff08;文字识别&#xff09;接口来实现识别提取照片内文字的功能。 效果预览 使用说明 1.点击界面下方圆形文字识别图标&#xff0c;弹出文字识别结果信息界面&#xff0c;显示当…

学习大数据DAY32 HTML基础语法和Flask库的使用

目录 HTML 超文本标记语言 Hyper Text Markup Language 上机练习 9 Flask 显示层 UI 前后端结合动态加载列表数据 flask 在 html 中的语法 上机练习 10 HTML 超文本标记语言 Hyper Text Markup Language 1.<html></html>: 根标签 2.<head></head&…