深入浅出分析C++ string底层原理

yizhihongxing

深入浅出分析C++ string底层原理

前言

在 C++ 中,string 类型是经常使用的字符串类型。了解 string 类的底层实现原理可以更好地理解其各种方法的行为,从而在编写程序时更加得心应手。本文将从以下几个方面对 string 类的底层实现进行说明:

  1. string 类的结构
  2. string 类的构造函数
  3. string 类的拷贝构造函数
  4. string 类的赋值操作符
  5. string 类的插入操作
  6. string 类的删除操作

string 类的结构

class string{
    char* str;
    size_t len;
};

如上所示,C++ 的 string 类内部主要包含了一个指向字符数组的指针,以及表示字符串长度的 size_t 类型变量。实际上,string 类在底层是使用一个动态分配的字符数组来保存字符串,而 str 指向的正是这个字符数组。由于字符数组是动态分配的,所以可以在程序运行时动态地改变字符串的长度。

string 类的构造函数

C++ 的 string 类有多个构造函数,在此只说明最基本的一个构造函数:

string::string(const char* s){
    len=std::strlen(s);
    str=new char[len+1];
    std::strcpy(str,s);
}

可以看出,string 类的构造函数主要做了两件事情:

  1. 计算字符串长度
  2. 动态分配字符数组,并将原始字符串拷贝进该数组

下面通过一个示例说明 string 类的构造函数行为:

#include <iostream>
#include <string>

using namespace std;

int main(){
    string s1("Hello, world!");
    cout << s1 << endl;
    return 0;
}

运行上述代码,输出结果为:

Hello, world!

可以看出,string 类的构造函数成功地将原始字符串 "Hello, world!" 拷贝进了动态分配的字符数组中,并正确地计算了字符串的长度。

string 类的拷贝构造函数

C++ 的 string 类还有一个拷贝构造函数,其定义如下:

string::string(const string& s){
    len=s.len;
    str=new char[len+1];
    std::strcpy(str,s.str);
}

可以看出,string 类的拷贝构造函数主要做了两件事情:

  1. 复制字符串长度
  2. 动态分配字符数组,并将原始字符串拷贝进该数组

下面通过一个示例说明 string 类的拷贝构造函数行为:

#include <iostream>
#include <string>

using namespace std;

int main(){
    string s1("Hello, world!");
    string s2(s1);
    cout << s2 << endl;
    return 0;
}

运行上述代码,输出结果为:

Hello, world!

可以看出,string 类的拷贝构造函数成功地将 s1 中的字符串拷贝进了 s2 中,并正确地计算了字符串的长度。

string 类的赋值操作符

C++ 的 string 类还重载了赋值操作符,其定义如下:

string::string& operator=(const string& s){
    if(this!=&s){
        delete[] str;
        len=s.len;
        str=new char[len+1];
        std::strcpy(str,s.str);
    }
    return *this;
}

可以看出,string 类的赋值操作符主要做了以下几件事情:

  1. 检查是否自我赋值,若自我赋值则直接返回。
  2. 删除原有的字符数组。
  3. 复制字符串长度。
  4. 动态分配字符数组,并将原始字符串拷贝进该数组。

下面通过一个示例说明 string 类的赋值操作符行为:

#include <iostream>
#include <string>

using namespace std;

int main(){
    string s1("Hello, world!");
    string s2;
    s2 = s1;
    cout << s2 << endl;
    return 0;
}

运行上述代码,输出结果为:

Hello, world!

可以看出,string 类的赋值操作符成功地将 s1 中的字符串拷贝进了 s2 中,并正确地计算了字符串的长度。

string 类的插入操作

C++ 的 string 类提供了多种插入操作,例如 insert 函数、 push_back 函数等。下面以 insert 函数为例进行说明:

string::iterator insert(iterator it,char c){
    size_t pos=it-str;
    size_t oldlen=len;
    len++;
    str=new char[len+1];
    std::memcpy(str,it,oldlen-pos);
    str[pos]=c;
    std::memcpy(str+pos+1,it+pos,oldlen-pos);
    return str+pos+1;
}

可以看出,insert 函数主要做了以下几件事情:

  1. 计算插入位置。
  2. 调整字符串长度。
  3. 动态分配字符数组,并将原始字符串拷贝进该数组。
  4. 在插入位置插入新字符。

下面通过一个示例说明 string 类的 insert 函数行为:

#include <iostream>
#include <string>

using namespace std;

int main(){
    string s1("world!");
    s1.insert(s1.begin(),'H');
    cout << s1 << endl;
    return 0;
}

运行上述代码,输出结果为:

Hello, world!

可以看出,insert 函数成功地在字符串 s1 的开头插入了字符 'H'。

string 类的删除操作

C++ 的 string 类提供了多种删除操作,例如 erase 函数、 pop_back 函数等。下面以 erase 函数为例进行说明:

string::iterator erase(iterator first,iterator last){
    size_t pos=first-str;
    size_t oldlen=len;
    len-=last-first;
    str=new char[len+1];
    std::memcpy(str,first,pos);
    std::memcpy(str+pos,last,oldlen-pos);
    return str+pos;
}

可以看出,erase 函数主要做了以下几件事情:

  1. 计算删除区间。
  2. 调整字符串长度。
  3. 动态分配字符数组,并将原始字符串拷贝进该数组。
  4. 删除指定区间的字符。

下面通过一个示例说明 string 类的 erase 函数行为:

#include <iostream>
#include <string>

using namespace std;

int main(){
    string s1("Hello, world!");
    s1.erase(5,7);
    cout << s1 << endl;
    return 0;
}

运行上述代码,输出结果为:

Hello!

可以看出,erase 函数成功地删除了字符串 s1 中位置 5-11 的字符。

结语

C++ 的 string 类提供了丰富的字符串操作方法,其底层实现涉及到动态分配字符数组、拷贝构造函数、赋值操作符等多个方面。希望本文的解释能够让读者更好地理解 string 类的底层工作方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入浅出分析C++ string底层原理 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 基于一致性hash算法 C++语言的实现详解

    下面是 “基于一致性Hash算法C++语言的实现详解” 的攻略。 简介 一致性Hash算法是分布式系统中常用的一种负载均衡算法。C++ 语言是一种高效的编程语言,有着广泛的应用。本篇攻略将通过分析一致性Hash算法的实现,详细讲解如何在C++语言中实现这一算法,并给出两个示例说明。 一致性Hash算法的实现 步骤一:将服务器节点映射到一个环上 一致性Hash…

    C 2023年5月22日
    00
  • JSON在Java中的使用方法实例

    下面是JSON在Java中的使用方法实例的详细攻略: 什么是JSON JSON是一种轻量级的数据交换格式,全称为JavaScript Object Notation。它是一种易于读写的文本格式,可与几乎所有编程语言一起使用,包括Java。 Java中的JSON库 Java中有多个库可以用于处理JSON,其中最流行的库是GSON和Jackson。这里我们以GS…

    C 2023年5月23日
    00
  • C++ STL标准库std::vector扩容时进行深复制原因详解

    C++ STL标准库std::vector是一个提供动态数组功能的容器,它提供了扩容机制,即当当前存储的元素个数达到容量限制时,会自动将容量扩大一倍,以适应更多元素的存储。但在扩容的过程中,每一个元素都必须进行深复制操作,这是因为在动态内存分配中,变量在内存中的位置不连续,因此需要将每个元素重新复制到新的内存位置上。 下面以两个简单示例详细说明std::ve…

    C 2023年5月23日
    00
  • C++程序代码优化的方法实例大全

    C++程序代码优化的方法实例大全 本文将为大家介绍C++程序代码优化的方法实例大全。通过本文的内容,可以帮助你更好地优化C++程序的代码,提高程序的性能。 一、代码优化的目标 代码优化的主要目标包括: 提高程序的运行速度和响应速度; 减少程序的内存占用和磁盘占用; 提高程序的可读性和可维护性。 二、优化方法 下面是几种常见的C++程序代码优化方法。 1. 使…

    C 2023年5月23日
    00
  • python使用Apriori算法进行关联性解析

    下面详细讲解一下“python使用Apriori算法进行关联性解析”的完整攻略。 一、什么是关联性分析和Apriori算法 1.1 关联性分析 关联性分析(Association Analysis)是一种寻找事物之间依存关系的方法,是数据挖掘领域中的一种常用方法。在销售、广告、推荐等领域具有广泛的应用。 关联性分析的基本目的是找出每个物品之间的关系,比如商品…

    C 2023年5月23日
    00
  • 约瑟夫环问题(数组法)c语言实现

    约瑟夫环问题(数组法)C语言实现 问题描述 有 $n$ 个人围成一圈,第 $m$ 个人开始报数,报到 $m$ 的人出圈,然后从出圈的下一个人开始继续报数,直到圈中只剩下一人。求出该人的编号。 解法思路 采用数组法解决约瑟夫环问题,主要的思路是:构建一个大小为 $n$ 的数组,来表示 $n$ 个人在约瑟夫环中的位置,将这些位置依次删除,直到只有一个人为止。 具…

    C 2023年5月23日
    00
  • C++程序操作文件对话框的方法

    现在我将为大家介绍一下在C++程序中操作文件对话框的方法。操作文件对话框是一个常用的功能,它可以帮助我们在程序中以交互式的方式选择文件并进行相关操作。下面是该攻略的详细步骤: 1. 确定操作系统类型 在编写代码之前,我们需要确定我们所使用的操作系统类型,不同的操作系统可能具有不同的文件对话框API接口。下面是Windows和macOS操作系统下涉及到的API…

    C 2023年5月23日
    00
  • Microsoft Visual C++ 程序的部署方法

    部署是将应用程序发布到用户机器上的过程,Microsoft Visual C++ 程序也需要进行部署才能在用户机器上运行。下面是 Microsoft Visual C++ 程序的部署方法的完整攻略: 1. 编译程序 在对程序进行部署之前,需要先确定最终版本的程序已经被编译成功。可以使用 Visual Studio 开发环境编译程序并生成可执行文件,或者使用命…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部