【C++】从string开始了解STL(上)

简介: 【C++】从string开始了解STL(上)

1.初识STL


1.什么是STL

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


2.STL的版本

  • 原始版本


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


  • P.J.版本


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


  • RW版本


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


  • SGI版本


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


3.STL的六大组件

5deb1f29f0986b5210fcc2cbbafd1d3e.png

对于STL的学习,这里推荐一个网站cplusplus.com


2.string

接下来就要正式进入到对STL的学习中啦,在对STL的学习过程中,需要注意的是

第一、熟悉库里面的STL的各种类模板的常用接口

第二、尝试去模拟实现库里面的类模板

注:在过程中,我们可能会遇到一些没有办法解决的问题,此时将会去查库里的源码,由于各个库中的实现方式不太一样,所以,在这里定一下,我们将会参考SGI版本的代码,结合侯捷老师的STL源码剖析去模拟实现。


1.string类模板

我们打开上文中推荐的网站,搜索string,会发现我们平常用的string其实是basic_string<char>,是类模板basic_string实例化出来的char类。

53937c4735ca505f949559452060d9f6.png

basic_string是一个类模板,可以通过传入不同的类型参数实例化出不同的类。

68850d1f68e3426b70de9c668eaed6dd.png

那么,对于string,为什么要使用一个类模板呢,在C语言中,对于字符串都是能够存放char类型的数据就可以了?


这是因为编码的问题,我们知道,在计算机中存放的数据都是0和1,为了让数据转换成人能看懂的东西,人们把特定的01序列给定义成某个字符,按照这种方式可以将计算机中的数据翻译出来,这就是编码,最初的编码方式就是将一些符号和大小写的26个字母与01序列对应,这就是ASCII码。

现在的常见编码方式

  • ASCII码

美国信息交换标准代码,是计算机存值和文字符号的对应关系,只有256个字符

  • Unicode

万国码,是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码包括了utf-8,utf-16,utf-32

utf-8兼容了ASCII,utf-8使用比较普遍,也比较节省空间

  • gbk

gbk即国标,针对中文而设计的编码,采用双字节编码


2.string类的构造函数

首先,一个类中必不可少的就是构造函数,我们来看一下string类的构造函数有什么

c631e3a2bf98f200769878b5a5f36acb.png

以上就是string的所有构造函数了,接下来让我们通过代码来实验一下:

void Test_Construct()
{
  char str[] = "hello string";//创建一个C语言的字符串
  string s1;//默认构造函数,不用传递任何参数,最终是s1中只有一个\0
  string s2(str);//使用C语言的字符串构造一个string类型的对象
  string s3(s2);//使用s2拷贝构造一个string类型的对象
  string s4(s3, 2, 5);//使用s3中的第二个位置开始长度为5的子串构造对象
  string s5(str, 8);//使用C语言的字符串构造一个指定长度的string类型
  string s6(10, 'a');//使用指定字符构造一个长度为10,内容为a的对象
  auto first = s2.begin();
  auto last = s2.end();
  string s7(first, last);//使用迭代器区间构造一个[first,last)的对象
  cout << "s1: " << s1 << endl;
  cout << "s2: " << s2 << endl;
  cout << "s3: " << s3 << endl;
  cout << "s4: " << s4 << endl;
  cout << "s5: " << s5 << endl;
  cout << "s6: " << s6 << endl;
  cout << "s7: " << s7 << endl;
}


运行上述代码,结果是:

52f9cdaaa27998e62fd2fdb1d9a7c09c.png

在上面的函数原型中,好像发现了一个之前没见过的东西,npos,什么是npos呢?查一下文档

5ce0bb7617ab1dcbb500448303319e12.png

可以看到npos是在类中定义的一个公共的静态成员常量,这个常量定义的值为-1,但是由于常量的类型是size_t,即unsigned int,所以表示的此类型可能的最大值。我们理解成字符串的结尾即可。


由于npos是string类中的成员常量,所以在使用npos的时候需要指定类域,即string::npos.


3.string内部数据访问

3e295b81579c3d1ffad240e175eee4ed.png

可以看到,对于数据访问,string提供了4个接口,其中两个是C++11新增的,看名字也可以得出,是获得字符串首元素和最后一个元素的,不常用,所以在此不过多赘述。我们主要关注at和operator[]这两个接口。

5ce5640e5a0c0dc096a7983c4c1ed15b.png

db40c39b432f79e9717f7b7e65caf20f.png

这两个接口都是能够拿到指定位置的值,其中operator[]是对[]的运算符重载。可以看到两个接口都重载了普通版本和const版本,用来应对权限放大的问题。

void Test_Element()
{
  string s = "hello string";
  cout << s.at(4) << endl;
  cout << s[4] << endl;
}


42bc7f490e8485baa255ed3f159f218e.png

相关文章
|
4天前
|
编译器 C语言 C++
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
14 1
|
17天前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
33 7
|
2月前
|
存储 编译器 C语言
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
64 4
|
2月前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
77 5
|
2月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
57 2
|
2月前
|
存储 算法 Linux
【c++】STL简介
本文介绍了C++标准模板库(STL)的基本概念、组成部分及学习方法,强调了STL在提高编程效率和代码复用性方面的重要性。文章详细解析了STL的六大组件:容器、算法、迭代器、仿函数、配接器和空间配置器,并提出了学习STL的三个层次,旨在帮助读者深入理解和掌握STL。
55 0
|
20天前
|
存储 编译器 C语言
【c++丨STL】vector模拟实现
本文深入探讨了 `vector` 的底层实现原理,并尝试模拟实现其结构及常用接口。首先介绍了 `vector` 的底层是动态顺序表,使用三个迭代器(指针)来维护数组,分别为 `start`、`finish` 和 `end_of_storage`。接着详细讲解了如何实现 `vector` 的各种构造函数、析构函数、容量接口、迭代器接口、插入和删除操作等。最后提供了完整的模拟实现代码,帮助读者更好地理解和掌握 `vector` 的实现细节。
30 0
|
3月前
|
存储 程序员 C++
C++常用基础知识—STL库(2)
C++常用基础知识—STL库(2)
89 5
|
3月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
30 1
|
2月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
109 5