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

深入浅出分析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日

相关文章

  • c++中try catch的用法小结

    当在C++代码中使用异常处理时,我们必须使用“try-catch”块来捕捉和处理异常。下面是一些关于“C++中try catch的用法小结”的攻略: 一、try-catch块的基本用法 使用try-catch块来捕捉异常,代码块包围了可能引发异常的代码。 try { //可能引发异常的代码 } catch(ExceptionType name) { //处理…

    C 2023年5月22日
    00
  • 如何通过指针突破C++类的访问权限

    通过指针突破C++类的访问权限,一般是利用C++的指针高级机制——类型强制转换。在C++中,类型强制转换提供了一种将一种类型的值转换为另一种类型的方法,常用的类型强制转换包括static_cast、dynamic_cast、reinterpret_cast和const_cast。其中,最常用的是static_cast,因为它能够在编译时刻确定类型,同时也比其…

    C 2023年5月23日
    00
  • ipython jupyter notebook中显示图像和数学公式实例

    下面是ipython jupyter notebook显示图像和数学公式的完整攻略: 显示图像 在ipython jupyter notebook中,我们可以使用matplotlib库来进行图像的显示。 步骤1:安装matplotlib库 在命令行终端中运行以下命令安装matplotlib库: pip install matplotlib 步骤2:导入mat…

    C 2023年5月22日
    00
  • java调用外部程序的方法及代码演示

    Java调用外部程序是一种常见场景,我们可以使用Java语言来方便地与外部程序进行交互。在本篇文章中,我将为大家详细讲解Java调用外部程序的方法及代码演示。 一、使用Runtime类调用外部程序 1.1 Runtime.getRuntime().exec()方法 Java提供了Runtime类来处理与系统进程的交互,我们可以使用该类的exec()方法来启动…

    C 2023年5月23日
    00
  • 用C语言实现猜数字游戏

    用C语言实现猜数字游戏完整攻略 1. 游戏规则 本猜数字游戏的规则非常简单,系统在1到100之间随机生成一个数字,然后玩家通过输入进行猜测,如果猜中则游戏胜利,若猜测的数字小于或大于目标数字,则系统会提示玩家重新猜测。 2. 程序实现 (1)首先我们需要定义一个目标数字,该数字需要随机生成。使用rand()函数可以生成一个随机数,我们通过加上1的操作让生成的…

    C 2023年5月23日
    00
  • C语言中的socket编程实例代码

    当我们需要在计算机程序中实现网络通信时,Socket 编程成为了一种非常重要的方式。C 语言是一种经典的编程语言,通过 C 语言实现 Socket 编程也是非常常见的。在接下来的讲解中,我们将会提供一个 C 语言中的 Socket 编程实例代码的完整攻略,并且会给出两条示例说明,让大家更好地理解代码的运用。 什么是 Socket 编程? Socket 是一种…

    C 2023年5月22日
    00
  • 一起来学习C语言的字符串转换函数

    一起来学习C语言的字符串转换函数 为什么要学习字符串转换函数 在C语言中,字符串处理非常常见,那么在字符串的处理过程中,必然需要将一些数字或其他类型的数据转换成字符串以实现一些输出的需求,或者将一个字符串转换成数字或其他类型的数据以实现一些计算的需求。因此,掌握字符串转换函数在C语言中是非常有必要和基础的。 两类字符串转换函数 在C语言中有两类字符串转换函数…

    C 2023年5月30日
    00
  • 详解C语言的预处理效果

    详解C语言的预处理效果 C语言的预处理器是所有C编译器的一部分。在编译代码之前,预处理器会处理源代码文件,执行一系列指令,以生成最终的代码文件。本文将详细介绍C语言的预处理器是如何工作的,以及预处理器有哪些常用指令。 预处理器的基础知识 在C程序中,任何以#字符开头的行都是预处理器指令。预处理指令可以出现在代码的任何位置,但通常出现在源代码文件的顶部。预处理…

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