C++ 中 string 类模拟实现:从零开始的旅程
模拟实现 C++ 中的 string
类是一个复杂且有趣的项目。这可以帮助你深入理解字符串操作的基础,内存管理,以及一些面向对象编程的概念。在实现过程中,我们需要从基本的内存管理、字符串操作方法和运算符重载等方面入手。下面是一个简化实现的过程:
基本结构
成员变量
char* data;
:用于存储字符串。size_t size;
:存储字符串长度。size_t capacity;
:存储当前分配的内存大小。
构造函数
- 默认构造函数。
- 通过
const char*
初始化。 - 复制构造函数。
- 移动构造函数。
析构函数
- 释放分配的内存。
成员函数
- 大小相关:
size()
、capacity()
、empty()
。 - 访问字符:重载
operator[]
和at()
。 - 修改字符串:
append()
、clear()
、resize()
。 - 内存管理:
reserve()
。
- 大小相关:
运算符重载
- 赋值运算符。
- 加号运算符
+
用于连接字符串。 - 比较运算符。
实现步骤
#include <iostream>
#include <cstring>
class MyString {
private:
char* data;
size_t size;
size_t capacity;
void initFromCStr(const char* cstr) {
size = std::strlen(cstr);
capacity = size;
data = new char[capacity + 1];
std::strcpy(data, cstr);
}
public:
// 默认构造函数
MyString() : data(new char[1]), size(0), capacity(0) {
data[0] = '\0';
}
// 通过 const char* 初始化
MyString(const char* cstr) {
initFromCStr(cstr);
}
// 复制构造函数
MyString(const MyString& other) {
initFromCStr(other.data);
}
// 移动构造函数
MyString(MyString&& other) noexcept : data(other.data), size(other.size), capacity(other.capacity) {
other.data = nullptr;
other.size = 0;
other.capacity = 0;
}
// 析构函数
~MyString() {
delete[] data;
}
// 赋值运算符
MyString& operator=(const MyString& other) {
if (this != &other) {
delete[] data;
initFromCStr(other.data);
}
return *this;
}
// 移动赋值运算符
MyString& operator=(MyString&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
size = other.size;
capacity = other.capacity;
other.data = nullptr;
other.size = 0;
other.capacity = 0;
}
return *this;
}
// 大小和容量
size_t getSize() const { return size; }
size_t getCapacity() const { return capacity; }
bool empty() const { return size == 0; }
// 访问字符
char& operator[](size_t idx) { return data[idx]; }
const char& operator[](size_t idx) const { return data[idx]; }
char& at(size_t idx) {
if (idx >= size) throw std::out_of_range("Index out of range");
return data[idx];
}
// 修改字符串
void clear() {
delete[] data;
data = new char[1];
data[0] = '\0';
size = 0;
capacity = 0;
}
void append(const MyString& other) {
size_t new_size = size + other.size;
if (new_size > capacity) {
reserve(new_size);
}
std::strcat(data, other.data);
size = new_size;
}
void reserve(size_t new_capacity) {
if (new_capacity > capacity) {
char* new_data = new char[new_capacity + 1];
std::strcpy(new_data, data);
delete[] data;
data = new_data;
capacity = new_capacity;
}
}
// 运算符重载
MyString operator+(const MyString& other) const {
MyString result(*this);
result.append(other);
return result;
}
};
int main() {
MyString str1("Hello");
MyString str2(" World!");
MyString str3 = str1 + str2;
std::cout << str3[0] << str3[1] << str3[2] << str3[3] << str3[4] << std::endl; // Prints: Hello
return 0;
}
说明
- 内存管理:通过使用
new
和delete
,管理字符串的分配和释放。 - 字符串操作:实现了基本的字符串连接和访问,这也可以扩展到更多的字符串操作。
- 异常处理:
at()
方法演示了如何处理异常,如访问越界。 - 对象语义:实现复制和移动语义,以确保对象的高效管理和使用。
这个实现仅仅是一个简单的示例,实际的 std::string
类要复杂得多,包括更多的优化和特性。你可以在此基础上扩展其他功能,如输入输出运算符重载、更多的字符串操作、改进的内存管理等。