小工具知识网

当前位置: 首页 > 行业知识 > 【C++深入浅出】STL之string用法详解

行业知识

【C++深入浅出】STL之string用法详解

2026-10-24 19:15:17 来源:互联网转载

���录

一. 前言

二. STL概要

2.1 什么是STL

2.2 STL的六大组件

2.3 STL的缺陷

三. string类概述

3.1 什么是string类

3.2 为什么要使用string类

四. string类的使用

4.1 包含头文件

4.2 构造函数

4.3 赋值运算符重载

4.4 容量操作

4.5 访问/遍历操作

4.6 查找修改操作

4.7 子串操作

​4.8 非成员函数


一. 前言

        经历了前面漫长且痛苦的学习,相比各位已经体会到了C++的魅力了叭 不要怕,学习完了模板之后,下面我们将进入STL的学习。相信你学完了STL之后,就会感受到使用C++是多么的顺畅,你甚至会不想回到使用C语言的时期,不信?就让我们拭目以待叭

二. STL概要

2.1 什么是STL

        把STL说得那么神,那STL究竟是什么呢?

        STL(standard template libaray - 标准模板库)是C++标准库的重要组成部分。其不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。有了STL后,像先前我们写的链表、顺序表、排序算法等等常见的底层数据结构和算法我们就可以不用自己造轮子了,我们可以站在前人的肩膀上,快速的进行开发。

2.2 STL的六大组件

        STL主要由以下六大组件构成:

        在后续的学习中,我们会逐个接触到,到时我们在进行详细讲解。

2.3 STL的缺陷

        尽管STL功能十分强大,但也存在着一些缺陷,下面我们列出了几点:

1. STL库的更新太慢了。上一版靠谱是C++98,中间的C++03基本没有修订,到C++11出来已经相隔了13年,STL才进一步更新。
2. STL目前没有支持线程安全。并发环境下需要我们自己加锁。且锁的粒度是比较大的。
3. STL极度的追求效率,导致内部实现比较复杂。比如类型萃取,迭代器萃取。
4. STL的使用会有代码膨胀的问题,比如同时使用vector,vector,vector时会生成多份代码,当然这是由于模板语法本身导致的。

三. string类概述

3.1 什么是string类

        string是C++标准库中用来表示字符序列的类,其中包含了许多关于操作单字节字符串的接口。string在底层实际上是basic_string模板类的别名,如下所示:

typedef basic_string string;

        可以看到,string是basic_string类模板的一个实例,其用char来实例化basic_string类模板,即string中存储的数据类型是char类型。故string只能用于处理单字节的序列,不能操作多字节或者变长字符的序列。

        string类的接口与常规容器的接口基本相同,只是添加了一些专门用来操作字符串的常规操作。

3.2 为什么要使用string类

        在C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP(面向对象编程)的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。而C++标准库的string就不存在这些问题,极大程度上方便了用户的使用。

四. string类的使用

4.1 包含头文件

        首先,要使用string类,我们需要包含头文件,并且由于string定义在命名空间std中,我们还需使用命名空间std,如下所示:

#includeusing namespace std;

接下来,我们将逐一介绍string的一些常用接口,由于string的接口以及重载版本非常多,详情读者可以参考以下链接:string - C++ Reference (cplusplus.com)https://legacy.cplusplus.com/reference/string/string/?kw=string

4.2 构造函数

        string也是个类,使用类时我们首先关注的就是它的构造函数,string常见的构造函数如下所示:

        使用方式如下所示: 

void test_constructor(){string str1; //无参构造string str2("abcd"); //C字符串构造string str3(str2); //拷贝构造string str4(str3, 1, 2); //子串构造string str5(str2.begin(), str2.begin()+3); //迭代器构造}

这里有个小问题:在子串构造中,npos的含义又是什么呢?它的定义如下:

static const size_t npos = -1;

由于size_t是无符号整形,而-1在内存中二进制表示为全1,故将-1赋值给npos后npos实际上是2^32-1,是一个非常大的数。

而string规定如果指定的长度len超过字符串的长度则只截取到字符串末尾,故将len的缺省值设置为npos的作用是当用户没有指定子串长度时默认截取到字符串末尾。

4.3 赋值运算符重载

        string重载了赋值运算符以便我们进行两个string对象之间的赋值,函数原型及说明如下所示:

         使用方式如下所示:

void test_assign(){string str1("abcd");string str2 = "ab"; //注意,这里不是赋值重载,这里是定义并初始化str2,故调用的是构造函数str2 = str1; //这里才是赋值重载,用string对象赋值str2 = "aaaa"; //用一个C字符串赋值str2 = 'c'; //用一个字符赋值,此时str2的长度变为1}

4.4 容量操作

        string类提供了许多与字符串容量相关的接口,如下表所示:

下面有几点注意事项:

  1. size()与length()方法底层实现原理完全相同,string出现得比STL早,那时string只有length方法,后面引入size()的原因是为了与其他STL容器的接口保持一致,一般情况下基本都是用size()。
  2. clear只是把有效字符的个数清空,不会改变底层空间的大小。
  3. reverse()的作用是为string保留空间,其不改变有效元素个数,当reserve的参数n小于

    string的底层总容量大小时,reserver不会改变容量大小。

  4. 使用reverse()时,有时编译器实际分配的大小会比我们指定的空间大,这取决于编译器,不过并不会造成什么影响,我们无需过多关心。

         使用方式如下所示: 

void test_capacity(){string str1 = "hello world";cout 

上一篇:怎么破解花生壳域名

下一篇:PHP招标源码深度解析,探索核心功能与源码结构之旅