前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【C++指南】string(二):深入探究 C++ `basic_string`:成员变量、函数全解析

【C++指南】string(二):深入探究 C++ `basic_string`:成员变量、函数全解析

作者头像
倔强的石头
发布于 2025-03-15 12:31:19
发布于 2025-03-15 12:31:19
5100
代码可运行
举报
文章被收录于专栏:C/C++指南C/C++指南
运行总次数:0
代码可运行

引言

在第一篇文章中【C++指南】string(一):string从入门到掌握,我们对 C++ 中 string 的起源、basic_string 模板类以及相关字符串类型有了初步的了解。

本文将深入剖析 basic_string 的成员变量、默认成员函数、迭代器、容量管理、修改操作等各类成员函数,详细介绍它们的使用方法、功能特点以及遵循的规则。

basic_string 的成员变量

内部结构概述

basic_string 类模板通常包含几个关键的成员变量来管理字符串数据,虽然具体实现可能因编译器而异,但一般会有以下几个核心部分:

  • 字符存储指针:指向存储字符串字符的动态分配内存区域。
  • 字符串长度:表示当前字符串中实际字符的数量。
  • 容量:表示当前分配的内存空间能够容纳的字符数量(包括字符串结束符)。
示例代码推测成员变量

虽然标准库没有公开 basic_string 的成员变量,但我们可以通过模拟实现来推测其可能的结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <typename CharT, typename Traits = std::char_traits<CharT>, typename Allocator = std::allocator<CharT>>
class basic_string {
private:
    CharT* _data;  // 字符存储指针
    size_t _size;  // 字符串长度
    size_t _capacity;  // 容量
    // 其他可能的成员变量和实现细节
};

默认成员函数

构造函数

basic_string 提供了多种构造函数重载,以满足不同的初始化需求。

在这里插入图片描述
在这里插入图片描述
  • 默认构造函数:创建一个空字符串。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <string>

int main() {
    std::string str;  // 默认构造,创建空字符串
    std::cout << "Empty string: " << str << std::endl;
    return 0;
}
  • 带字符串字面量的构造函数:使用字符串字面量初始化字符串。其中这个构造函数是日常中最常用的
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::string str("Hello, World!");
std::cout << "Initialized with literal: " << str << std::endl;
  • 带重复字符的构造函数:使用指定字符重复多次初始化字符串。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::string str(5, 'a');  // 初始化为 "aaaaa"
std::cout << "Repeated characters: " << str << std::endl;
  • 拷贝构造函数:创建一个新字符串,其内容是另一个字符串的副本。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::string original("Original");
std::string copy(original);
std::cout << "Copied string: " << copy << std::endl;
析构函数

析构函数负责在字符串对象生命周期结束时释放其占用的内存资源,防止内存泄漏。在使用 std::string 时,我们无需手动管理内存,析构函数会自动完成这些工作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    std::string str("Temporary");
    // 当 str 离开作用域时,析构函数自动调用
}
赋值运算符重载

赋值运算符用于将一个字符串的值赋给另一个字符串。

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::string source("Source");
std::string destination;
destination = source;
std::cout << "Assigned string: " << destination << std::endl;

迭代器

迭代器类型

basic_string 支持多种迭代器类型,用于遍历字符串中的字符。

  • 正向迭代器begin()end() 分别返回指向字符串起始和结束位置(最后一个字符的下一个位置)的迭代器。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::string str("Iterate");
for (auto it = str.begin(); it != str.end(); ++it) {
    std::cout << *it << " ";
}
std::cout << std::endl;
  • 反向迭代器rbegin()rend() 分别返回指向字符串末尾和起始位置(第一个字符的前一个位置)的反向迭代器。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (auto rit = str.rbegin(); rit != str.rend(); ++rit) {
    std::cout << *rit << " ";
}
std::cout << std::endl;
  • 常量迭代器cbegin()cend()crbegin()crend() 用于遍历常量字符串,确保不会修改字符串内容。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const std::string constStr("Constant");
for (auto cit = constStr.cbegin(); cit != constStr.cend(); ++cit) {
    std::cout << *cit << " ";
}
std::cout << std::endl;
迭代器的使用规则
  • 迭代器可以进行递增(++)和递减(--)操作,用于移动到下一个或前一个字符位置。
  • 可以使用 * 运算符解引用迭代器,获取当前指向的字符。
  • 在使用迭代器时,要确保迭代器的有效性,避免越界访问。

容量管理

容量相关函数
  • size()length():返回字符串中当前存储的字符个数,这两个函数功能相同。
  • 一般我们都会选择使用size函数,因为size函数在C++中的其他容器中也是通用的,只有length函数是因为历史发展原因string所独有的
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::string str("Capacity");
std::cout << "Size: " << str.size() << ", Length: " << str.length() << std::endl;
  • capacity():返回字符串当前已分配的内存空间能够容纳的字符个数,通常大于或等于 size()
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::cout << "Capacity: " << str.capacity() << std::endl;
  • reserve():预先分配一定大小的内存空间,避免在字符串增长过程中频繁的内存重新分配,提高性能。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
str.reserve(20);
std::cout << "Reserved capacity: " << str.capacity() << std::endl;
  • resize():改变字符串的长度。
  • 若新长度小于原长度,则会截断字符串;
  • 若新长度大于原长度,会在字符串末尾填充指定字符(默认为空字符);
  • 若新长度大于string容量,则会扩容,并在补充的部分添加指定字符
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
str.resize(3);
std::cout << "Resized string: " << str << std::endl;
str.resize(5, 'x');
std::cout << "Resized and filled: " << str << std::endl;
容量管理规则
  • 当字符串长度超过当前容量时,basic_string 会自动重新分配更大的内存空间,并将原有字符复制到新的内存区域。
  • reserve() 只是预先分配内存,不会改变字符串的长度。
  • resize() 会直接改变字符串的长度,可能会导致内存重新分配。

修改操作

插入操作

一般我们用的最多的还是 operator+=,相当于尾插,而insert和erase非必要尽量不用,因为前插涉及到挪动数据,会存在效率的问题

insert() 函数用于在字符串的指定位置插入字符或字符串。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::string str("Insert");
str.insert(2, "abc");  // 在位置 2 插入 "abc"
std::cout << "Inserted string: " << str << std::endl;
删除操作

erase() 函数用于删除字符串中指定位置或范围的字符。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
str.erase(2, 3);  // 从位置 2 开始删除 3 个字符
std::cout << "Erased string: " << str << std::endl;
追加操作
  • push_back():在字符串末尾添加一个字符。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
str.push_back('!');
std::cout << "Pushed back: " << str << std::endl;
  • append()operator+=:用于在字符串末尾追加字符或字符串。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
str.append(" World");
std::cout << "Appended string: " << str << std::endl;
str += "!";
std::cout << "Appended with +=: " << str << std::endl;
修改操作规则
  • 插入和删除操作可能会导致内存重新分配和字符移动,影响性能。
  • 追加操作通常比插入操作更高效,因为它只在字符串末尾进行操作。

其他相关函数

查找函数
  • find():在字符串中查找指定的字符或子串,返回其第一次出现的位置,如果未找到则返回 std::string::npos
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::string str("Find me");
size_t pos = str.find("me");
if (pos != std::string::npos) {
    std::cout << "Found at position: " << pos << std::endl;
} else {
    std::cout << "Not found" << std::endl;
}
  • rfind():从字符串末尾开始查找,返回最后一次出现的位置。
替换函数

replace() 用于将字符串中指定范围的字符替换为其他字符或子串。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
str.replace(0, 4, "Replace");
std::cout << "Replaced string: " << str << std::endl;
比较函数

compare() 用于比较两个字符串的大小,返回一个整数表示比较结果。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::string str1("Hello");
std::string str2("World");
int result = str1.compare(str2);
if (result < 0) {
    std::cout << str1 << " is less than " << str2 << std::endl;
} else if (result > 0) {
    std::cout << str1 << " is greater than " << str2 << std::endl;
} else {
    std::cout << str1 << " is equal to " << str2 << std::endl;
}

总结

本文详细介绍了 C++ basic_string 的成员变量、默认成员函数、迭代器、容量管理、修改操作以及其他相关函数。通过深入了解这些内容,我们可以更加灵活和高效地使用 std::string 及其相关类型。在实际编程中,合理运用这些函数可以提高代码的可读性和性能,避免常见的错误和问题。 后续我们还将进一步探讨 basic_string 的底层实现和一些高级应用场景。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
从 12s 到 200ms,MySQL 两千万订单数据 6 种深度分页优化全解析
那晚,大约晚上 11 点,我与 Chaya 在丽江的洱海酒店享受两人世界的快乐,电商平台的运维大群突然炸开了锅。
码哥字节
2025/02/25
3530
从 12s 到 200ms,MySQL 两千万订单数据 6 种深度分页优化全解析
交付工程师准备工作
交付工程师(Delivery Engineer)是在软件开发项目中,负责将软件产品交付给客户并确保其顺利运行的工程师。他们的工作主要涵盖以下几个方面:
GeekLiHua
2025/01/21
1000
交付工程师准备工作
mysql┃explain 都不会用?怎么优化?
现在的java开发人员越来越多,竞争也越来越激烈,moon在某钩招聘网站上发布了一个岗位需求,不到短短1天就收到20多份简历,大部分都是应届一年两年的,新鲜血液越来越多,我们也要不断的提升自己才能够不被挤下去,大家可以看下各大网站的java岗位3年以上的招聘需求:
moon聊技术
2021/07/28
6600
mysql┃explain 都不会用?怎么优化?
MySQL怎样优化千万级数据
这里讨论的情况是在MySQL一张表的数据达到千万级别。表设计很烂,业务统计规则又不允许把sql拆成多个子查询。
闻说社
2024/05/21
1740
MySQL怎样优化千万级数据
10道常考SQL笔试题
题目:在 Employees 表中,获取每个部门(department)薪资最高的员工的姓名、部门和工资。表结构如下:
SQL数据库开发
2024/09/24
1780
10道常考SQL笔试题
【收藏】MySQL 超全优化清单(可执行系列)
先从一般的语句优化开始,其实对于很多规范大家并不陌生,可就是在用的时候,无法遵从,希望今天大家再过一遍,可以养成一种良好的数据库编码习惯。
lyb-geek
2024/07/17
2490
【收藏】MySQL 超全优化清单(可执行系列)
MySQL Hints:控制查询优化器的选择
MySQL Hints是一组特殊的注释或指令,可以直接嵌入到SQL查询中,以改变MySQL优化器的默认行为。这些Hints通常被用于解决性能问题,或者当开发者比优化器更了解数据分布和查询特性时,来指导优化器选择更好的查询计划。
公众号:码到三十五
2024/06/05
5960
MySQL Hints:控制查询优化器的选择
MySQL中的SQL优化建议那么多,该如何有的放矢
今天早上看到同事的一个优化需求,优化的时间其实不多,但是对于这条SQL的优化思考了很多,希望有一些参考。
jeanron100
2019/11/15
6940
最强总结!十大数据库索引类型详解!!
数据库索引是数据库性能优化的重要基础。选择正确的索引类型对提升查询性能至关重要。本文将通过理论讲解+案例分析的方式,帮您深入理解各类索引的原理和应用!
SQL数据库开发
2024/12/24
7150
最强总结!十大数据库索引类型详解!!
数据库优化 – SQL优化[通俗易懂]
前面一篇文章从实例的角度进行数据库优化,通过配置一些参数让数据库性能达到最优。但是一些“不好”的SQL也会导致数据库查询变慢,影响业务流程。本文从SQL角度进行数据库优化,提升SQL运行效率。
全栈程序员站长
2022/10/04
3.6K0
数据库优化 – SQL优化[通俗易懂]
工作中数据库优化技巧
内容整理于网络 一、EXPLAIN 做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划。 EXPLAIN 输出格式 EXPLAIN 命令的输出内容大致如下: mysql root@localhost:youdi_auth> explain select * from auth_user\G; ***************************[ 1. row ]*************************** id | 1 select_type |
若与
2018/04/25
7820
工作中数据库优化技巧
MySQL上亿数据查询优化:实践与技巧
随着大数据时代的到来,数据库管理系统需要处理越来越多的数据。MySQL作为一种流行的关系型数据库管理系统,被广泛应用于各类业务场景。然而,当数据量达到上亿级别时,查询性能可能会显著下降,严重影响应用的响应速度和用户体验。本文将详细介绍MySQL在处理上亿数据时的查询优化技巧,并通过实践案例展示如何有效提升查询性能。
洛秋_
2024/07/13
7060
MySQL的索引是什么?怎么优化?
索引类似大学图书馆建书目索引,可以提高数据检索的效率,降低数据库的IO成本。MySQL在300万条记录左右性能开始逐渐下降,虽然官方文档说500~800w记录,所以大数据量建立索引是非常有必要的。MySQL提供了Explain,用于显示SQL执行的详细信息,可以进行索引的优化。
吴生
2018/04/03
1.5K0
MySQL的索引是什么?怎么优化?
MySQL实战面试题(附案例答案+建表语句+模拟数据+案例深度解析),练完直接碾压面试官
使用YEAR()和MONTH()函数从signup_date字段中提取年份和月份,并匹配给定的条件。
小白的大数据之旅
2024/11/20
1610
8 种常见SQL错误用法,你千万别犯!
分页查询是最常用的场景之一,但也通常也是最容易出问题的地方。比如对于下面简单的语句,一般 DBA 想到的办法是在 type, name, create_time 字段上加组合索引。这样条件排序都能有效的利用到索引,性能迅速提升。
好好学java
2020/03/02
1K0
MySQL通过索引优化-这里可能有你不知道的索引优化细节(二)
用执行计划分别测试一下union all、in和or,发现union all分两步执行,而in和or只用了一步,效率高一点。
行百里er
2020/12/02
8960
MySQL通过索引优化-这里可能有你不知道的索引优化细节(二)
【随笔】MySQL 索引测试和性能优化指南
在数据库查询优化的过程中,索引扮演着至关重要的角色。合理使用索引不仅能大幅提升查询效率,还能降低数据库的负载。然而,不同类型的索引在不同场景下的表现可能存在较大差异,因此深入理解各类索引的特性以及 EXPLAIN 关键字的查询分析能力尤为重要。
框架师
2025/02/21
1680
【随笔】MySQL 索引测试和性能优化指南
MySQL 覆盖索引与延迟关联
本期来谈谈覆盖索引与延迟关联。在此之前,我们先简单建立一个订单表 Orders 用于举例说明。表中共包含 3 个字段:
江不知
2020/09/08
1.7K0
MySQL 覆盖索引与延迟关联
最强总结!数据库优化完全指南!!
数据库优化是提升应用性能的关键环节。本文将从多个维度系统地介绍数据库优化的方法和实践经验。
SQL数据库开发
2024/11/21
2290
最强总结!数据库优化完全指南!!
MySQL数据库基础与实战应用
MySQL是一种开源的关系型数据库管理系统,广泛应用于各种规模的应用程序和网站中。它以其稳定性、高性能和可扩展性而闻名,成为许多开发者和企业首选的数据库解决方案。本文将介绍MySQL数据库的基础知识,并探讨其在实际应用中的应用场景。
海拥
2023/09/01
2540
推荐阅读
相关推荐
从 12s 到 200ms,MySQL 两千万订单数据 6 种深度分页优化全解析
更多 >
LV.3
yu1inengineer
目录
  • 引言
  • basic_string 的成员变量
    • 内部结构概述
    • 示例代码推测成员变量
  • 默认成员函数
    • 构造函数
    • 析构函数
    • 赋值运算符重载
  • 迭代器
    • 迭代器类型
    • 迭代器的使用规则
  • 容量管理
    • 容量相关函数
    • 容量管理规则
  • 修改操作
    • 插入操作
    • 删除操作
    • 追加操作
    • 修改操作规则
  • 其他相关函数
    • 查找函数
    • 替换函数
    • 比较函数
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档