好的!下面是一个完整教程:如何手搓一个 STL 风格的 string
容器类(自定义 String 类),它模仿 std::string
的常用接口,具备基本的字符串管理功能,包括构造、拷贝、移动、运算符重载等,结构清晰、逻辑易懂,适合作为 C++ 面向对象 + 运算符重载 + RAII 内存管理 的综合练习。
✅ 一、项目目标
实现一个类 MyString
,支持以下功能:
功能 | 示例 |
---|---|
构造与析构 | MyString s("hello"); |
拷贝与移动 | MyString s2 = s1; |
字符访问 | s[0] |
长度查询 | s.size() |
拼接运算 | s1 + s2 |
比较运算 | ==, !=, < |
输出重载 | std::cout << s; |
🧱 二、核心类声明
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
#include <cstring>
class MyString {
private:
char* data;
size_t len;
public:
// 构造 & 析构
MyString(); // 默认构造
MyString(const char* str); // C风格字符串构造
MyString(const MyString& other); // 拷贝构造
MyString(MyString&& other) noexcept; // 移动构造
~MyString(); // 析构
// 运算符重载
MyString& operator=(const MyString& other); // 拷贝赋值
MyString& operator=(MyString&& other) noexcept; // 移动赋值
char& operator[](size_t index);
const char& operator[](size_t index) const;
MyString operator+(const MyString& other) const;
bool operator==(const MyString& other) const;
bool operator<(const MyString& other) const;
size_t size() const;
// 流输出
friend std::ostream& operator<<(std::ostream& os, const MyString& s);
};
#endif
⚙️ 三、核心实现(MyString.cpp
)
#include "MyString.h"
// 默认构造
MyString::MyString() : data(new char[1]{'\0'}), len(0) {}
// C风格字符串构造
MyString::MyString(const char* str) {
len = strlen(str);
data = new char[len + 1];
strcpy(data, str);
}
// 拷贝构造
MyString::MyString(const MyString& other) {
len = other.len;
data = new char[len + 1];
strcpy(data, other.data);
}
// 移动构造
MyString::MyString(MyString&& other) noexcept : data(other.data), len(other.len) {
other.data = nullptr;
other.len = 0;
}
// 析构
MyString::~MyString() {
delete[] data;
}
// 拷贝赋值
MyString& MyString::operator=(const MyString& other) {
if (this != &other) {
delete[] data;
len = other.len;
data = new char[len + 1];
strcpy(data, other.data);
}
return *this;
}
// 移动赋值
MyString& MyString::operator=(MyString&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
len = other.len;
other.data = nullptr;
other.len = 0;
}
return *this;
}
// 索引访问
char& MyString::operator[](size_t index) {
return data[index];
}
const char& MyString::operator[](size_t index) const {
return data[index];
}
// 拼接
MyString MyString::operator+(const MyString& other) const {
char* new_data = new char[len + other.len + 1];
strcpy(new_data, data);
strcat(new_data, other.data);
MyString result(new_data);
delete[] new_data;
return result;
}
// 比较
bool MyString::operator==(const MyString& other) const {
return strcmp(data, other.data) == 0;
}
bool MyString::operator<(const MyString& other) const {
return strcmp(data, other.data) < 0;
}
// 长度
size_t MyString::size() const {
return len;
}
// 输出流重载
std::ostream& operator<<(std::ostream& os, const MyString& s) {
os << s.data;
return os;
}
🎯 四、使用示例(main.cpp)
#include "MyString.h"
int main() {
MyString a("Hello");
MyString b("World");
MyString c = a + MyString(" ") + b;
std::cout << "c: " << c << std::endl;
std::cout << "Length: " << c.size() << std::endl;
if (a < b) {
std::cout << a << " is less than " << b << std::endl;
}
MyString d = c;
std::cout << "Copy d: " << d << std::endl;
MyString e = std::move(d);
std::cout << "Move e: " << e << std::endl;
}
🧠 五、你学到的知识点
知识点 | 说明 |
---|---|
RAII 原则 | 动态内存管理用构造/析构控制 |
拷贝控制五法则 | 构造、析构、拷贝构造、赋值、移动 |
运算符重载 | +、==、[]、<< |
资源管理 | 深拷贝 vs. 移动语义 |
面向对象封装 | 接口友好,隐藏实现细节 |
📦 六、扩展方向(可选挑战)
- ✅ 支持 UTF-8 / 多字节字符处理
- ✅ 实现
insert
,erase
,find
,substr
等接口 - ✅ 实现迭代器接口(支持
begin()
/end()
) - ✅ 兼容 C++ STL allocator 策略
- ✅ 编写单元测试 & 性能测试
如果你希望我把这个项目打包成完整的工程目录结构(含 Makefile / CMake / 注释文档),或想在此基础上进一步封装为库,请告诉我,我可以继续帮你完善它。是否要我做成一个 GitHub 项目模板?
发表回复