1. 为什么需要自己封装String类
在C++开发中,字符串处理是最基础也是最频繁的操作之一。虽然标准库提供了std::string,但实际项目中我们经常会遇到需要自定义字符串类的情况。以下是几个典型的场景:
-
性能优化需求:标准库的std::string在某些场景下可能不是最优选择。比如处理大量短字符串时,频繁的内存分配会影响性能。通过自定义实现,可以采用小字符串优化(SSO)技术,将短字符串直接存储在对象内部,避免堆内存分配。
-
特殊内存管理:在嵌入式系统或高频交易等对内存管理有特殊要求的场景中,可能需要实现自己的内存池或特定的分配策略。
-
接口统一:不同库使用不同的字符串类型(如Qt的QString、MFC的CString等),自定义String类可以作为适配层,提供统一的接口。
-
教学目的:实现一个完整的String类是理解C++类设计、内存管理、运算符重载等核心概念的最佳实践。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础String类设计
2.1 类的基本框架
我们先从最基本的String类开始,逐步添加功能:
cpp复制class String {
private:
char* m_data; // 存储字符串数据
size_t m_size; // 字符串长度
public:
// 构造函数
String(const char* str = nullptr);
// 拷贝构造函数
String(const String& other);
// 移动构造函数
String(String&& other) noexcept;
// 析构函数
~String();
// 赋值运算符
String& operator=(const String& other);
// 移动赋值运算符
String& operator=(String&& other) noexcept;
// 其他成员函数...
};
2.2 内存管理实现
正确的内存管理是String类的核心。以下是构造函数的实现示例:
cpp复制String::String(const char* str)
: m_data(nullptr), m_size(0)
{
if (str) {
m_size = strlen(str);
m_data = new char[m_size + 1]; // +1 for null terminator
strcpy(m_data, str);
}
}
注意:这里使用了C风格的字符串操作函数,在实际项目中可以考虑使用更安全的替代方案,如strncpy或memcpy。
2.3 拷贝控制成员
实现正确的拷贝语义至关重要:
cpp复制// 拷贝构造函数
String::String(const String& other)
: m_data(nullptr), m_size(other.m_size)
{
if (other.m_data) {
m_data = new char[m_size + 1];
strcpy(m_data, other.m_data);
}
}
// 拷贝赋值运算符
St
