一、引言
在 C++ 编程中,string是处理字符串的核心类,相较于 C 风格字符数组,它自动管理内存、提供丰富操作接口,极大提升了开发效率与代码安全性。本文将从深浅拷贝原理、string底层模拟实现、标准库string常用函数详解、迭代器与容器实战、字符串数字相加案例等维度,全面梳理类的核心知识,形成从原理到实战的完整体系。
文章介绍了 C++ string 类的深浅拷贝原理及自定义实现,涵盖构造析构、运算符重载、resize 等功能。详解标准库常用函数如初始化、容量管理、查找替换等。展示迭代器遍历方式及 STL 算法配合。最后通过字符串数字相加案例演示超大数处理逻辑。

在 C++ 编程中,string是处理字符串的核心类,相较于 C 风格字符数组,它自动管理内存、提供丰富操作接口,极大提升了开发效率与代码安全性。本文将从深浅拷贝原理、string底层模拟实现、标准库string常用函数详解、迭代器与容器实战、字符串数字相加案例等维度,全面梳理类的核心知识,形成从原理到实战的完整体系。
string浅拷贝仅复制对象成员变量的值,若成员包含指针,仅拷贝指针地址,使多个对象指向同一块内存。
深拷贝会为指针成员重新分配独立内存,并复制原数据,使每个对象拥有专属内存空间,互不干扰。
string类的默认拷贝机制。C++ 标准库std::string的拷贝构造函数、赋值运算符均实现深拷贝,修改一个对象不会影响另一个:
#include <iostream>
#include <string>
using namespace std;
int main() {
string original = "Hello, World!";
string copy1(original); // 拷贝构造(深拷贝)
string copy2 = original; // 赋值运算符(深拷贝)
copy1[0] = 'h'; // 修改 copy1,original、copy2 不受影响
cout << original << endl; // Hello, World!
cout << copy1 << endl; // hello, World!
cout << copy2 << endl; // Hello, World!
return 0;
}
#include <iostream>
#include <cstring>
#include <assert.h>
using namespace std;
class MyString {
private:
char* _str;
size_t _size;
size_t _capacity;
public:
// 构造函数
MyString(const char* str) {
if (str == nullptr) {
_str = nullptr;
_size = 0;
_capacity = 0;
} else {
_size = strlen(str);
_capacity = _size;
_str = new char[_capacity + 1];
strcpy(_str, str);
}
}
// 拷贝构造(深拷贝)
MyString(const MyString& other) {
_size = other._size;
_capacity = other._capacity;
_str = new char[_capacity + 1];
memcpy(_str, other._str, _size + 1);
}
// 赋值运算符(现代写法)
MyString& operator=(MyString tmp) {
swap(tmp);
return *this;
}
// 移动赋值(C++11,转移资源)
MyString& operator=(MyString&& other) noexcept {
if (this != &other) {
delete[] _str;
_str = other._str;
_size = other._size;
_capacity = other._capacity;
other._str = nullptr;
}
return *this;
}
// 析构函数
~MyString() {
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
// 交换成员
void swap(MyString& s) {
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
};
基于strcmp实现字典序比较:
bool operator>(const MyString& other) const {
return strcmp(_str, other._str) > 0;
}
bool operator<(const MyString& other) const {
return strcmp(_str, other._str) < 0;
}
bool operator>=(const MyString& other) const {
return !(*this < other);
}
bool operator<=(const MyString& other) const {
return !(*this > other);
}
bool operator==(const MyString& other) const {
return strcmp(_str, other._str) == 0;
}
bool operator!=(const MyString& other) const {
return !(*this == other);
}
调整字符串长度,支持缩小、扩大与填充字符:
void resize(size_t new_size, char fill_char = '\0') {
if (new_size < _size) {
_size = new_size;
_str[_size] = '\0';
} else {
reserve(new_size);
for (size_t i = _size; i < new_size; ++i) {
_str[i] = fill_char;
}
_size = new_size;
_str[_size] = '\0';
}
}
// 预留容量
void reserve(size_t n) {
if (n > _capacity) {
char* new_str = new char[n + 1];
strcpy(new_str, _str);
delete[] _str;
_str = new_str;
_capacity = n;
}
}
支持MyString + MyString、MyString + const char*:
MyString operator+(const MyString& other) const {
size_t new_size = _size + other._size;
char* new_data = new char[new_size + 1];
strcpy(new_data, _str);
strcat(new_data, other._str);
MyString res(new_data);
delete[] new_data;
return res;
}
MyString operator+(const char* str) const {
size_t len = strlen(str);
size_t new_size = _size + len;
char* new_data = new char[new_size + 1];
strcpy(new_data, _str);
strcat(new_data, str);
MyString res(new_data);
delete[] new_data;
return res;
}
string迭代器本质是字符指针:
typedef char* iterator;
typedef const char* const_iterator;
iterator begin() {
return _str;
}
iterator end() {
return _str + _size;
}
const_iterator begin() const {
return _str;
}
const_iterator end() const {
return _str + _size;
}
string s0; // 空字符串
string s1("hello"); // 字面量初始化
string s2 = s1; // 拷贝初始化
string s3(5, 'a'); // 重复字符:"aaaaa"
size()/length():返回字符串长度(功能完全一致)capacity():返回已分配内存容量reserve(n):预分配容量,减少扩容shrink_to_fit():释放多余内存,使容量等于长度clear():清空字符串内容,不释放内存+=、append()find()、rfind()、find_first_of()(未找到返回string::npos)substr(pos, len)(省略len取到末尾)replace(pos, len, str)insert()、erase()(效率低,少用)[](不检查越界)、at()(越界抛异常)to_string()(C++11,标准通用)atoi()(C 风格)、stoi()(C++11,抛异常)stringstream(跨平台、支持任意类型)cin:以空格 / 换行分隔,无法读取带空格字符串getline(cin, str):读取整行,包含空格(需处理前导换行符)cin.ignore(); // 清空缓冲区换行
geline(cin, str);
for (size_t i = 0; i < s.size(); ++i) cout << s[i];
string::iterator it = s.begin();
while (it != s.end()) cout << *it++;
string::reverse_iterator rit = s.rbegin();
while (rit != s.rend()) cout << *rit++;
for (auto& ch : s) cout << ch;
需包含<algorithm>:
reverse(s.begin(), s.end()); // 反转
sort(s.begin(), s.end()); // 排序
处理超大数字(超出整型范围),模拟手工加法:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string addStrings(string num1, string num2) {
int i = num1.size() - 1, j = num2.size() - 1;
string res;
int carry = 0;
while (i >= 0 || j >= 0 || carry) {
int val1 = i >= 0 ? num1[i--] - '0' : 0;
int val2 = j >= 0 ? num2[j--] - '0' : 0;
int sum = val1 + val2 + carry;
carry = sum / 10;
res.push_back(sum % 10 + '0');
}
reverse(res.begin(), res.end());
return res;
}
// 测试
int main() {
cout << addStrings("123456789", "987654321") << endl; // 1111111110
return 0;
}
string默认深拷贝。string:需实现构造、析构、拷贝构造、赋值运算符,重载常用运算符与迭代器。string:接口丰富,优先使用+=、reserve优化性能,注意find、substr边界。
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online