【C++从0到王者】第九站:String基本介绍及使用(上)

简介: 【C++从0到王者】第九站:String基本介绍及使用

一、String的基本使用

当我们想要使用string库的时候,我们需要先包上头文件string。然后还需要展开命名空间,如果没有展开,就需要指定了,如下所示是string类的一些基本用法,我们可以注意到与普通类的用法还是比较一致的。

#include<iostream>
#include<string>
using namespace std;
int main()
{
  string s1;
  std::string s2;
  std::string name("张三");
  name = "张飞";
  return 0;
}

二、String构造相关的成员函数

在这里,我们就需要去查看文档了。我们使用这个网站来进行查阅cplusplus.com/我们,直接搜索String即可

我们可以注意到下面有这个类的成员函数的使用方法

在string类中,大概有100多个成员函数,我们不可能全部记住,所以我们只需要掌握最常用的即可,剩下的我们需要的时候查文档即可

1.String构造函数

我们进入文档的构造函数部分,我们发下有七个构造函数

我们可以注意到:

  1. 第一个是无参的默认构造函数
  2. 第二个是拷贝构造
  3. 第四个是用一个c语言的字符串去构造
  4. 第六个是使用使用一个字符,用n个字符去构造

如上四个是比较常用的构造函数。他们的使用如下所示:

int main()
{
  //无参的默认构造
  string s1;
  //用字符串去构造
  string s2("hello world");
  //用n个字符去构造
  string s3(10, '*');
  //拷贝构造
  string s4(s2);
  cout << s1 << endl;
  cout << s2 << endl;
  cout << s3 << endl;
  cout << s4 << endl;
  return 0;
}

如下所示为运行结果,在上面这段代码中,我们可以注意到流插入运算符可以直接运用于string类,这是因为流插入运算符已经在库里面被重载过了。除此之外,我们也有< ,>,==等运算符的重载,这些运算符重载的比较规则与C语言的strcmp是一样的。根据ASCII码来进行比较。但是如果要使用流插入等进行打印的时候,注意优先级

我们再来看一些不常用的几个函数:

  1. 第三个构造函数的功能是拷贝构造的一个版本,pos是某个的下标,将对象的pos这个下标开始,将len长度的字符串拷贝构造给一个新对象。我们也可以注意到len有一个缺省参数,这个缺省参数是npos,它的值是-1。但由于它接收的是无符号的数,所以这个-1会变得非常之大。可以认为是如果胜利了len,就从pos位置拷贝构造完这个函数的一个应用就是切割字符串,如下所示,当然下面的方法比较笨拙需要我们手动算位置。我们未来可以来自动搜索位置
  2. 第五个函数的作用是拷贝字符数组的前n进行类对象的初始化
  3. 第七个函数是涉及到迭代器的使用,我们在后文在详细了解

2.String析构函数

如下所示是析构函数的的使用说明,事实上析构函数我们是不需要自己去管的。因为它生命周期结束的时候自动调用

3.operator=运算符重载

如上所示,这个运算符重载有三个函数,他们由于参数不同又构成了函数重载。

  1. 第一个的作用是用一个对象运算符重载赋值给一个对象。
  2. 第二个的作用是用一个字符串去赋值一个对象
  3. 第三个是用一个字符去赋值一个对象

但是我们其实可以注意到,第二个和第三个其实没有也是可以的。因为编译器又隐式类型转换,它会自动用这个字符串或者字符去构造一个类对象,然后将这个类对象去拷贝构造给一个对象。但是编译器优化后就直接将构造+拷贝构造优化为了构造

4.String增删查改之增

我们创建好一个对象后,我们需要对其进行增删查改等操作。

当我们想要在一个对象后面增加一个字符的时候,我们使用push_back函数

当我们想要增加一个字符串的时候,我们使用append这个函数

这里我们要注意的是,append虽然有很多成员函数,但我们最喜欢最常用追加字符串的那个函数

int main()
{
  string s1("hello");
  s1.push_back(' ');
  s1.append("world");
  cout << s1 << endl;
  return 0;
}

还需要注意的是,虽然c语言中有strcat这个也是追加字符串的函数,但是使用string的效率更高。而且还会涉及空间不够的问题,而string不涉及空间不够的问题,空间不够直接扩容即可,因为string的本质其实就是一个顺序表,它在类里面的成员变量大致如下

class string
{
public:
private:
  char* _str;
  size_t _size;
  size_t _capacity;
};

虽然push_back和append很好,但是还有一个函数是operator+=,我们更喜欢使用它

它有三个函数重载,它可以加一个类对象,加一个字符串,加一个字符

事实上operator+=的内部就是复用push_back和append实现的。

但是append并不能完全被替代掉,我们继续观察以下append的函数重载有哪些

我们发现它与构造函数是非常相似的。功能也是类似的

  1. 第一个是追加一个对象
  2. 第二个是将对象第subpos位置开始,后面sublen个字符追加到一个对象上去
  3. 第三个是追加一个字符串
  4. 第四个是追加字符串的前n个
  5. 第五个是追加n个c字符

5. operator[]运算符重载

这个运算符重载是比较强大的,在c语言中,它就是一个解引用。在string中也可以实现类似的功能,比如说当我们想要遍历一个string对象的时候,我们就可以利用这个下标和operator[]运算符重载实现,注意这个size成员函数用于计算对象有效字符的个数的。

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

我们知道size成员函数是计算有效字符的个数的,而\0字符并不是有效字符,他是一个特殊的标识字符。所以第二次遍历的时候并不会遍历到\0

而如果我们遍历的时候在size函数后+1,是可以访问到\0的,但是编译器不会显示的打印出来,所以打印结果还是原来的样子

我们还注意到,operator[]返回的是引用,所以是可以直接进行修改的。由此我们有了下面的代码

这样一来string就可以像数组一样玩了。

但是需要注意的是,它与数组的解引用是具有天差地别的,底层是完全不一样的

相关文章
|
1月前
|
存储 编译器 C语言
C++_String增删查改模拟实现
C++_String增删查改模拟实现
48 0
|
9天前
|
存储 安全 C语言
【C++】string类
【C++】string类
|
存储 编译器 Linux
标准库中的string类(中)+仅仅反转字母+字符串中的第一个唯一字符+字符串相加——“C++”“Leetcode每日一题”
标准库中的string类(中)+仅仅反转字母+字符串中的第一个唯一字符+字符串相加——“C++”“Leetcode每日一题”
|
11天前
|
编译器 C++
标准库中的string类(上)——“C++”
标准库中的string类(上)——“C++”
|
21天前
|
存储 算法 C语言
【C++初阶】8. STL初阶 + String类
【C++初阶】8. STL初阶 + String类
48 1
|
21天前
|
C语言 C++
【C++初阶】9. string类的模拟实现
【C++初阶】9. string类的模拟实现
38 1
|
26天前
|
NoSQL C++
c++中包含string成员的结构体拷贝导致的double free问题
c++中包含string成员的结构体拷贝导致的double free问题
9 0
|
6天前
|
存储 编译器 C语言
c++的学习之路:5、类和对象(1)
c++的学习之路:5、类和对象(1)
22 0
|
1月前
|
存储 C++ 容器
C++入门指南:string类文档详细解析(非常经典,建议收藏)
C++入门指南:string类文档详细解析(非常经典,建议收藏)
39 0
|
6天前
|
C++
c++的学习之路:7、类和对象(3)
c++的学习之路:7、类和对象(3)
19 0