【C++ String】

文章目录

  • [【C++ STL】string类](#【C++ STL】string类)
    • [1. C++11 语法补充(前置知识)](#1. C++11 语法补充(前置知识))
      • [1.1 auto 关键字](#1.1 auto 关键字)
      • [1.2 范围 for 循环](#1.2 范围 for 循环)
    • [2. 标准库中的 string 类](#2. 标准库中的 string 类)
      • [2.1 常见构造函数](#2.1 常见构造函数)
      • [2.2 容量操作](#2.2 容量操作)
      • [2.3 修改与访问](#2.3 修改与访问)
    • [3. string 底层结构的差异 (VS vs G++)](#3. string 底层结构的差异 (VS vs G++))
      • [3.1 VS (Visual Studio) 结构](#3.1 VS (Visual Studio) 结构)
      • [3.2 G++ (Linux) 结构](#3.2 G++ (Linux) 结构)
    • [4. 对于模拟实现string 类的浅拷贝问题](#4. 对于模拟实现string 类的浅拷贝问题)
      • [4.1 浅拷贝及其危害](#4.1 浅拷贝及其危害)
      • [4.2 现代版深拷贝](#4.2 现代版深拷贝)
    • 总结

【C++ STL】string类

摘要: 在C语言中,字符串以 \0 结尾,相关库函数与数据分离,且需用户管理内存,易越界。C++ STL 提供的 string 类将数据与操作结合,极大提高了开发效率。


1. C++11 语法补充(前置知识)

在学习 string 及后续容器前,需掌握两个高效的 C++11 特性。

1.1 auto 关键字

auto 不再是简单的存储类型指示符,而是类型指示符,让编译器在编译期自动推导变量类型。

使用规则:

  • 指针与引用: 声明指针时 autoauto* 等效;声明引用时必须加 &
  • 多变量声明: 同一行声明多个变量时,类型必须相同,因为编译器只根据第一个变量推导类型。
  • 限制: auto 不能作为函数参数(但可做返回值),且不能直接声明数组。
cpp 复制代码
int main() {
    int x = 10;
    auto a = &x;    // 推导为 int*
    auto* b = &x;   // 推导为 int*
    auto& c = x;    // 推导为 int&
    
    // auto arr[] = {1, 2, 3}; // 错误:不能声明数组
    return 0;
}

1.2 范围 for 循环

范围 for 能够自动迭代、取数据并判断结束,极大简化了容器遍历。

原理: 范围 for 的底层通过替换为迭代器实现。

cpp 复制代码
string str("hello world");

// 1. 遍历打印
for (auto ch : str) {
    cout << ch << " ";
}

// 2. 遍历并修改(必须用引用)
for (auto& ch : str) {
    ch += 1; 
}

2. 标准库中的 string 类

使用时请包含头文件 #include <string>

2.1 常见构造函数

函数名称 功能说明
string() 构造空字符串
string(const char* s) 用 C 格式字符串构造
string(size_t n, char c) 生成 n 个字符 c 的字符串
string(const string& s) 拷贝构造函数

2.2 容量操作

函数名称 功能说明
size() 返回字符串有效字符长度(最常用)
capacity() 返回空间总大小
empty() 检测字符串是否为空
clear() 清空字符内容,但不缩减容量
reserve(n) 预留空间,不改变有效元素个数
resize(n, c) 改变长度,多出的空间用字符 c 填充

重点区分: reserve 只影响容量大小;resize 既可能改变容量,也会实实在在改变 size(填充或截断数据)。

2.3 修改与访问

  • operator[]: 像数组一样通过索引 s[i] 访问字符。
  • operator+=: 推荐使用,可直接追加字符或字符串。
  • c_str(): 返回 C 格式字符串,常用于调用 C 语言接口。
  • find(): 从指定位置向后查找,找不到则返回 string::npos

3. string 底层结构的差异 (VS vs G++)

3.1 VS (Visual Studio) 结构

VS 采用 SBO (Small Buffer Optimization) 优化:

  • 32位下占 28字节
  • 包含一个联合体:长度 < 16 字节时存放在内部数组,提高效率;>= 16 字节时才在堆上开辟空间。

3.2 G++ (Linux) 结构

G++ 采用 COW (Copy-On-Write,写时拷贝) 技术:

  • 32位下仅占 4字节(一个指针)。
  • 指针指向的堆空间包含:有效长度、容量、引用计数及实际数据。

4. 对于模拟实现string 类的浅拷贝问题

4.1 浅拷贝及其危害

如果不写拷贝构造,系统默认的拷贝会导致两个对象指向同一块空间。这会引发:

  1. 修改互相影响
  2. 析构崩溃 (同一块空间被 delete 两次)。

4.2 现代版深拷贝

利用构造函数和 swap 函数,让临时对象帮我们完成繁琐的工作。

cpp 复制代码
class String {
public:
    // 构造
    String(const char* str = "") {
        _str = new char[strlen(str) + 1];
        strcpy(_str, str);
    }

    // 拷贝构造:现代写法
    String(const String& s) : _str(nullptr) {
        String tmp(s._str); // 调用构造函数开空间
        swap(_str, tmp._str); // 交换资源
    }

    // 赋值重载:传值参数触发拷贝构造产生副本 s
    String& operator=(String s) {
        swap(_str, s._str); // 副本 s 销毁时顺便带走旧资源
        return *this;
    }

    ~String() {
        delete[] _str;
    }
private:
    char* _str;
};

总结

掌握 string 类不仅要会用其丰富的接口,更要理解底层深浅拷贝的逻辑及不同编译器的实现差异。在算法面试中,大数加法和双指针反转是极其常见的考点,建议熟练背诵相关模板。

相关推荐
小程同学>o<2 小时前
嵌入式之C/C++(四)预处理
c语言·c++·面试题库·嵌入式面试题
历程里程碑2 小时前
Linux 18 进程控制
linux·运维·服务器·开发语言·数据结构·c++·笔记
爱装代码的小瓶子2 小时前
【c++与Linux基础】文件篇(5)- 文件管理系统:
linux·开发语言·c++
xu_yule2 小时前
网络和Linux网络-15(IO多路转接)reactor编程-服务器
linux·运维·服务器·c++
Howrun7772 小时前
C++_错误处理
开发语言·c++
近津薪荼2 小时前
优选算法——滑动窗口3(子数组)
c++·学习·算法
方便面不加香菜2 小时前
c++入门基础
c++
雍凉明月夜2 小时前
瑞芯微RV1106G3板端部署
c++·人工智能·深度学习
Smart-Space2 小时前
cpphtmlbuilder-c++灵活构造html
c++·html