STL —— string(1)

目录

1. 模板

1.1 泛型编程

1.2 函数模板

1.2.1 函数模板概念

1.2.2 函数模板格式

1.2.3 函数模板的原理

1.2.4 显式实例化

1.2.5 模板参数的匹配原则

1.3  类模板

1.3.1 类模板定义格式

 1.3.2 类模板的实例化

2.  STL —— string类

2.1 STL 简介

2.2 标准库中的string类

2.2.1 string类的构造函数 

2.3 string类容量操作

2.4 遍历string类

2.4.1 operator[]

2.4.2 迭代器iterator

2.4.3 范围for


1. 模板

1.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 函数模板

1.2.1 函数模板概念

  • 函数模板与函数参数类型无关,编译器不会直接调用模板,而是利用模板实例化出一个函数,然后在调用。

1.2.2 函数模板格式

  • 函数模板通常采用 template<typename T1, typename T2......>的形式,这里的 typename 可以换成 class,例如:
template <typename T>
void Swap(T& x, T& y)
{T t = x;x = y;y = t;
}int main()
{int a1 = 10, a2 = 20;Swap(a1, a2);return 0;
}

1.2.3 函数模板的原理

  • 函数模板实际上是编译器检测你所传入的参数的类型,然后自动帮你生成一份函数,之后再调用。

1.2.4 显式实例化

  • 那如果我们传入的参数类型不同那该怎么办呢?比如:

template <class T>
T Add(T& left, T& right)
{return left + right;
}int main()
{int a1 = 10, a2 = 20;double d1 = 1.1, d2 = 2.2;Add(a1, d1);return 0;
}

这个时候编译器会编译不通过,因为当你传入a1 的 时候,编译器自动会把 T 推演成 int 类型, 但是看到 double 又会把 T 推演成 double 类型,编译器不知道该听谁的,所以会报错,那该如何处理呢? 这里给出三种方法:

  1. 强制类型转换:
    template <class T>
    // 注意这里的第二个参数要加上const
    T Add(T& left, const T& right)
    {return left + right;
    }int main()
    {int a1 = 10, a2 = 20;double d1 = 1.1, d2 = 2.2;Add(a1, (int)d1);return 0;
    }

    由于在强制类型转换的过程中会产生临时变量,并且临时变量具有常性,不可被修改,而且传的是引用,因此要加上const。

  2. 多加一个模板参数类型
    template <class T1, class T2>
    T2 Add(T1& left, T2& right)
    {return left + right;
    }int main()
    {int a1 = 10, a2 = 20;double d1 = 1.1, d2 = 2.2;Add(a1, d1);return 0;
    }
  3. 显示实例化
    template <class T>
    // 这边的const也是类似的道理
    T Add(const T& left, const T& right)
    {return left + right;
    }int main()
    {int a1 = 10, a2 = 20;double d1 = 1.1, d2 = 2.2;Add<double>(a1, d1);return 0;
    }

    显示实例化会强制编译器把 T 推演成某个类型,格式就例如:Add<double>(a1, d1);

1.2.5 模板参数的匹配原则

  • 一个模板和一个与模板同名的函数可以同时存在,并且模板也可以生成与这个函数参数类型相同的函数,但是如果存在同名函数,且参数类型和要传入的参数类型相同,会首先调用这个函数,如果想让编译器自己生成,就可以用显示实例化,例如:

template <class T>
T Add(const T& left, T& right)
{return left + right;
}int Add(int left, int right)
{return left + right;
}int main()
{int a1 = 10, a2 = 20;Add(a1, a2);Add<int>(a1, a2);return 0;
}
  • 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板,例如:
// 专门处理int的加法函数
int Add(int left, int right)
{return left + right;
}// 通用加法函数
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{return left + right;
}
void Test()
{Add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化Add(1, 2.0); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数
}
  •  模板函数不允许自动类型转换,但普通函数可以进行自动类型转换:
// 因为普通函数可以进行自动类型转换,因此不需要加上const
int Add(int left, int right)
{return left + right;
}int main()
{int a1 = 10;double d2 = 20;Add(a1, d2);return 0;
}

1.3  类模板

1.3.1 类模板定义格式

  • template<class T1, class T2, ..., class Tn>

如下是实现简单的栈类型个类模板:

template<class T>
class Stack
{
public:Stack(int capacity):_a(new T[capacity]),_top(0),_capacity(capacity){}void PushBack(const T& val){//CheckCapacity()_a[_top++] = val;}~Stack(){delete[] _a;_top = _capacity = 0;}private:T* _a;int _top;int _capacity;
};
  • 如果要声明定义分离的话,要加入模板参数列表
template<class T>
void Stack<T>::PushBack(const T& val)
{//CheckCapacity()_a[_top++] = val;
}template<class T>
Stack<T>::Stack(int capacity):_a(new T[capacity]), _top(0), _capacity(capacity)
{}

 1.3.2 类模板的实例化

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

2.  STL —— string类

2.1 STL 简介

STL(Standard Template Library)是C++标准库中的一个重要组成部分,提供了丰富的通用数据结构和算法模板。STL的设计目标是提供可复用、高效和类型安全的组件,以便开发人员可以方便地处理各种常见的数据结构和算法问题。

STL主要由以下几个组件组成:

  1. 容器(Containers):STL提供了一系列的容器类模板,如 vectorlistdequesetmap等。这些容器类模板封装了常见的数据结构,如数组、链表、双向队列、集合和映射等,开发人员可以根据需要选择合适的容器来存储和组织数据。

  2. 算法(Algorithms):STL提供了一组常用的算法模板,如排序、查找、合并、删除、遍历等。这些算法可以用于不同的容器,并且具有高度的可组合性,开发人员可以将不同的算法组合在一起以实现复杂的操作。

  3. 迭代器(Iterators):迭代器是STL中用于遍历容器元素的对象,它提供了一种通用的访问方式,使得算法可以独立于容器进行操作。STL提供了多种类型的迭代器,包括输入迭代器、输出迭代器、正向迭代器、双向迭代器和随机访问迭代器,每种迭代器都具有不同的特性和功能。

  4. 函数对象(Function Objects):函数对象是可调用对象,可以像函数一样使用。STL中的算法可以接受函数对象作为参数,以实现不同的操作。STL提供了一些标准的函数对象,如谓词(Predicate)、函数适配器(Function Adapters)等,同时也支持自定义的函数对象。

  5. 分配器(Allocators):STL中的容器使用分配器来管理内存的分配和释放。分配器允许开发人员自定义内存管理策略,以满足特定的需求,如内存池分配器、定制的内存分配器等。

STL的设计理念是以泛型编程为核心,通过使用模板和参数化类型,提供通用的、可复用的组件。STL组件之间的协调和配合使得开发人员能够以更高的抽象层次进行编程,从而提高开发效率并降低代码复杂性。

使用STL可以使得C++开发人员能够更加专注于解决问题本身,而不必过多关注底层的数据结构和算法实现。STL已经成为C++编程中的重要工具和标准实践,广泛应用于各个领域的软件开发。

2.2 标准库中的string类

  •  cplusplus 网站给出的 string 底层的介绍:

string - C++ Reference (cplusplus.com)icon-default.png?t=N7T8https://legacy.cplusplus.com/reference/string/string/

2.2.1 string类的构造函数 

  • cplusplus 网站给出的string类构造函数的介绍:

string::string - C++ Reference (cplusplus.com)icon-default.png?t=N7T8https://legacy.cplusplus.com/reference/string/string/string/

  • 对应的构造函数的用法:
  • 注意这里的 "<<" 和 ">>" 重载库中已经给出,所以可以直接用:
int main()
{string s0; // (1)string s1("hello world"); // (4)string s2(s1); // (2)string s3(s1, 5); // (3)string s4("hello world", 5); // (5)string s5(6, '#'); // (6)cout << s0 << endl;cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;cout << s5 << endl;return 0;
}

2.3 string类容量操作

size返回字符串有效长度。 

2.4 遍历string类

2.4.1 operator[]

  • string类中已经把[]重载了,可以获取pos位置的元素。
  • string类中的容量操作有一个size,可以返回字符串有效字符长度。
  • begin() 和 end() 在迭代器中,begin获取第一个字符的迭代器,end获取最后一个字符下一个位置的迭代器。

int main()
{string s0; // (1)string s1("hello world"); // (4)string s2(s1); // (2)for (size_t i = 0; i < s2.size(); ++i){cout << s2[i] << " ";}cout << endl;for (size_t i = 0; i < s2.size(); ++i){s2[i]++;}cout << endl;for (size_t i = 0; i < s2.size(); ++i){cout << s2[i] << " ";}cout << endl;return 0;
}

 

2.4.2 迭代器iterator

  • 迭代器的用法类似于指针,在string中可能使用[]比较方便,但是在 链表,二叉树等链式结构就得用迭代器了。
int main()
{string s0; // (1)string s1("hello world"); // (4)string s2(s1); // (2)string::iterator it = s2.begin();while (it != s2.end()){cout << *it << " ";++it;}it = s2.begin();while (it != s2.end()){*it += 5;++it;}cout << endl;it = s2.begin();while (it != s2.end()){cout << *it << " ";++it;}return 0;
}

2.4.3 范围for

int main()
{string s0; // (1)string s1("hello world"); // (4)string s2(s1); // (2)for (auto e : s2){cout << e << " ";}return 0;
}

 

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

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

相关文章

微服务篇-C 深入理解第一代微服务(SpringCloud)_IV 深入理解Hystrix断路器

原创作者&#xff1a;田超凡&#xff08;程序员田宝宝&#xff09; 版权所有&#xff0c;引用请注明原作者&#xff0c;严禁复制转载 Part 1 理论部分 1 什么是微服务系统中的高可用&#xff1f; 在复杂的大型微服务系统中&#xff0c;高可用相关的技术方案非常重要&#x…

怎样隐藏查询和分组?

发布查询时&#xff0c;遇到信息量较大需要提前制作好&#xff0c;但不用马上发布的查询&#xff0c;该怎样隐藏查询和分组&#xff1f; &#x1f4cc;使用教程 01“开始”和“暂停”查询 如果想要隐藏查询&#xff0c;可以通过点击绿色开始按钮来暂停查询&#xff0c;暂停后的…

C++多态实现原理深度解析

C多态实现原理深度解析 目录 C多态实现原理深度解析 一、引言&#xff1a;多态性的基本概念与重要性 二、虚函数表&#xff08;VTable&#xff09;与虚函数指针&#xff08;VPtr&#xff09; 三、动态绑定与静态绑定 四、纯虚函数与抽象基类 五、继承与多态的关系 六、多…

【软考高项】十五、信息系统工程之系统集成

1、集成基础 定义&#xff1a;通过硬件平台、网络通信平台、数据库平台、工具平台、应用软件平台将各类资源有机、高效地集成到一起&#xff0c;形成一个完整的工作台面 基本原则包括:开放性、结构化、先进性和主流化 2、网络集成 包括&#xff1a;传输子系统、交换子系统、…

调试西门子G120STO模式出现O.F1600等一系列报警

目录 一、现象描述 二、 解决经历 三、结果展示 四、总结 一、现象描述 在调试使用西门子G120的STO功能时&#xff0c;一直无法使用&#xff0c;变频器也一直在报警(RDY灯红灯快闪、SAFE灯黄灯快闪)。在博图上查询发现下面一系列的故障报警。 二、 解决经历 也查询了很多网…

Vue中的状态管理Vuex,基本使用

1.什么是Vuex? Vuex是专门为Vue.js设计的状态管理模式;特点:集中式存储和管理应用程序中所有组件状态,保证状态以一种可预测的方式发生变化。 1.1.什么是状态管理模式? 先看一个单向数据流的简单示意图 state:驱动应用的数据源 view:以声明方式将state映射到视图 actions:…

实施业务连续性方案

实施业务连续性方案&#xff0c;可以提高组织在面对突发事件和业务中断时的韧性和恢复能力&#xff0c;保障业务的持续运行和服务的可用性。请注意&#xff0c;具体的方案内容应根据组织的特点、业务需求和风险状况进行定制化。 一、目标与范围 确定业务连续性方案的目标&#…

导入GPG密钥的方法

在配置Docker时&#xff0c;发现Docker官方和阿里云导入gpg秘钥的方法不同&#xff0c;借此记录。 Docker官方 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg 优点: 安全性: 这种方法不会直接将密钥添加到APT的密…

SAP前台处理:物料主数据创建<MM01>之会计视图

一、背景&#xff1a; 终于来到了物料主数据&#xff0c;我觉得物料账是SAP最重要的一项发明&#xff0c;也一直是SAP的一项重要优势&#xff0c;物料账记录了一个个物料的生生不息&#xff1b; 本章主要讲解物料主数据和财务相关的主要内容&#xff1a;这里特别提示由于作者…

c语言扫雷改进版

目录 文章目录 主体 整体架构流程 技术名词解释 技术细节 测试情况 文章目录 概要整体架构流程技术名词解释技术细节测试情况 主体 主体包括菜单&#xff0c;游戏规则简绍&#xff0c;选择进行与否 int main() {int input;srand((unsigned int)time(NULL));do{ menu()…

GPT实战系列-LangChain的Prompt提示模版构建

GPT实战系列-LangChain的Prompt提示模版构建 LangChain GPT实战系列-LangChain如何构建基通义千问的多工具链 GPT实战系列-构建多参数的自定义LangChain工具 GPT实战系列-通过Basetool构建自定义LangChain工具方法 GPT实战系列-一种构建LangChain自定义Tool工具的简单方法…

科技云报道:造完“大模型”,“具身智能”将引领AI下一个浪潮?

科技云报道原创。 资深机器人专家Eric Jang不久前曾预言&#xff1a;“ChatGPT 曾在一夜之间出现。我认为&#xff0c;有智慧的机器人技术也将如此。” 3月13日深夜&#xff0c;一段人形机器人的视频开始热传。 在视频中&#xff0c;Figure的人形机器人&#xff0c;可以完全…

postgresql查看数据库占用空间大小

在PostgreSQL中&#xff0c;查看数据库及数据表当前数据的占用量可以通过执行特定的SQL查询来实现。以下是几种常用的方法&#xff1a; 1.查看单个数据表的占用空间大小&#xff1a; 使用pg_size_pretty和pg_total_relation_size函数可以获取特定数据表的占用空间大小&#xf…

H12-821_887

887.当业务饥配置为VLANPool时&#xff0c;若用户在一定时间内连续获取IP地址失败且配置了dhcp update vlan assignment threshold命令&#xff0c;则会触发VLANPoo1为用户分配新的VLAN&#xff0c;使用户在新VLAN中重新获取IP地址。 A.TRUE B.FALSE 答案&#xff1a;A 注释&a…

【算法】差分算法详解(模板)

类似于数学中的求导和积分之间的关系&#xff0c;差分可以看成前缀和的逆运算。 差分数组&#xff1a; 首先给定一个原数组a&#xff1a;a[1], a[2], a[3],,,,,, a[n]; 然后我们构造一个数组b &#xff1a; b[1] ,b[2] , b[3],,,,,, b[i]; 使得 a[i] b[1] b[2 ] b[3] ,,,…

Java实现10万,并发去重,优雅地处理重复请求!

对于一些用户请求&#xff0c;在某些情况下是可能重复发送的&#xff0c;如果是查询类操作并无大碍&#xff0c;但其中有些是涉及写入操作的&#xff0c;一旦重复了&#xff0c;可能会导致很严重的后果&#xff0c;例如交易的接口如果重复请求可能会重复下单。 重复的场景有可…

C语言实现飞行小游戏

以下是一个简单的C语言实现飞行小游戏的代码示例。这个游戏中&#xff0c;一个飞机需要控制左右移动来避开悬挂在屏幕上方的飞行杂物&#xff0c;代码如下&#xff1a; #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h&…

CAD建筑版2024 安装教程

CAD建筑版是一种专门用于建筑设计和绘图的CAD软件版本。它提供了专业的建筑设计工具和功能&#xff0c;帮助建筑师、设计师和工程师在建筑领域进行快速、准确和高效的设计工作。 CAD建筑版具备建筑相关的库和元素&#xff0c;用户可以方便地使用预定义的建筑符号和元素进行建筑…

网络基础(二)

1、应用层 程序员写的一个个解决我们实际问题, 满足我们日常需求的网络程序, 都是在应用层&#xff1b; 1.1、再谈 "协议" 协议是一种 "约定". socket api的接口, 在读写数据时, 都是按 "字符串" 的方式来发送接收的. 如果我们要传输一些 "…

设计模式学习笔记 - 设计原则与思想总结:2.运用学过的设计原则和思想完善之前性能计数器项目

概述 在 《设计原则 - 10.实战&#xff1a;针对非业务的通用框架开发&#xff0c;如何做需求分析和设计及如何实现一个支持各种统计规则的性能计数器》中&#xff0c;我们讲解了如何对一个性能计数器框架进行分析、设计与实现&#xff0c;并且实践了一些设计原则和设计思想。当…