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,一经查实,立即删除!

相关文章

怎样隐藏查询和分组?

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

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

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:…

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

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

c语言扫雷改进版

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

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

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

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

类似于数学中的求导和积分之间的关系&#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] ,,,…

CAD建筑版2024 安装教程

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

网络基础(二)

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

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

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

IP代理技术革新:探索数据采集的新路径

引言&#xff1a; 随着全球化进程不断加深&#xff0c;网络数据采集在企业决策和市场分析中扮演着愈发重要的角色。然而&#xff0c;地域限制和IP封锁等问题常常给数据采集工作带来了巨大挑战。亿牛云代理服务凭借其强大的网络覆盖和真实住宅IP资源&#xff0c;成为解决这些问…

Metasploit Pro 4.22.2-2024021501 (Linux, Windows) - 专业渗透测试框架

Metasploit Pro 4.22.2-2024021501 (Linux, Windows) - 专业渗透测试框架 Rapid7 Penetration testing, Release Feb 15, 2024 请访问原文链接&#xff1a;https://sysin.org/blog/metasploit-pro-4/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页…

verilog设计-CDC:单bit脉冲快时钟域到慢时钟域

一、前言 当单bit信号由快时钟域传递给慢时钟域时&#xff0c;快时钟域的异步信号最小可为快时钟信号的一个时钟周期脉冲&#xff0c;快时钟域的单时钟周期脉冲长度小于慢时钟域的时钟周期&#xff0c;很有可能该脉冲信号在慢时钟域的两个时钟上升沿之间&#xff0c;导致该脉冲…

Django数据库查询

聚合查询 分组查询 F与Q查询 默认情况下,用Q包裹的两个条件,用逗号分割也是and关系 choices参数 只要某个字段的可能性是完全可以列举出来的,可以采取choices参数 该gender字段存的还是数字,但是如果数字在上面的元组列举范围内,该怎么获取对应的值,如果不在范围内,会怎…

20240321, 字符串操作,STRING.H,字符串函数的实现

啥意思&#xff0c;这个循环是&#xff1f;每次给P分配一个字节&#xff0c;然后把那个位置写入0&#xff1f;但是0是整数吧&#xff1f;他需要四个字节&#xff1f;&#xff1f;&#xff1f;这和0地址有什么关系……啊啊啊啊啊 一&#xff0c;字符串操作 1.0 字符数组 补 0…

LeetCode_Java_递归系列(题目+思路+代码)

206.反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]以此类推&#xff0c;直到反转结束返回头结点 class Solution {public ListNode rever…

是德科技N9020A信号分析仪

181/2461/8938产品概述&#xff1a; N9020A MXA信号分析仪通过增加针对新一代技术的信号分析和频谱分析能力&#xff0c;具备了中档分析仪的更高性能。它突破了以往分析仪的极限&#xff0c;支持业界更快的信号和频谱分析,实现了速度与性能的更佳优化。 速度 测试速度超过其它…

linux之shell脚本基础

1.构建基础脚本 1.1 创建shell脚本 1.1.1 第一行需要指定使用的shell # 用作注释行.shell并不会处理脚本中的注释行,但是第一行的注释,会告诉shell使用哪个shell来运行脚本. #!/bin/bash 1.1.2 让shell找到你的脚本 直接运行脚本会提示-bash: a.sh: command not found.因…

一套键盘鼠标控制两台电脑 Mouse Without Borders

有两台电脑&#xff0c;一台笔记本一台台式机&#xff0c;拥有各自拥有鼠标和键盘&#xff0c;但总是需要切换&#xff0c;感觉太麻烦&#xff0c;想找个简单的方式&#xff0c;不需要额外操作就能同时操作这两台电脑。无意间发现了一个微软软件Mouse Without Borders&#xff…