快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。
🚩在之前的文章中我们学会了对string类函数的使用,现在让我们对其进行模拟实现吧~🚩
目录
💯引言
💯string 类的功能需求分析
💯模拟实现的关键步骤和代码解析
1.类的定义
2.构造函数实现
2.1 默认构造函数
2.2 用 C 风格字符串初始化的构造函数
2.3 拷贝构造函数
3. 析构函数实现
4.获取字符串长度函数
5.字符串比较函数
6.字符串连接函数
7.字符串插入函数
8.字符串删除函数
9.字符串加法操作符重载
10.下标操作符重载
11.赋值操作符重载
💯内存管理相关函数(如reserve和resize)
1.reserve函数
2.resize函数
💯示例用法
💯总结
💯引言
在 C++ 编程中,字符串处理很常见且重要。标准库的 string 类提供了方便的操作接口。了解其内部实现原理,对提升编程技能很有帮助。
🐸你是否曾经好奇过 string 类是如何实现这些强大功能的呢?
🎦本文将介绍如何模拟实现一个简单的 string 类🎦
💯string 类的功能需求分析
- 存储字符串数据
用字符数组存储字符序列,它能通过👉索引访问字符,方便操作。还需动态管理存储空间,以适应不同长度字符串,避免内存问题。
- 字符串长度获取
要有获取字符串长度(字符个数)的方法,这对很多操作都必要。
- 字符串比较
要能比较两个字符串大小,用于排序、查找等操作。
- 字符串连接
能把两个字符串连接成一个新字符串,像组合单词成句子。
- 字符串修改
包括末尾添加、指定位置插入和删除部分字符串等操作,以灵活处理字符串。
- 内存管理
合理分配和释放内存,避免泄漏和浪费。字符串长度变化时要自动调整存储空间。
💯模拟实现的关键步骤和代码解析
1.类的定义
class MyString {
private:char* data; // 存储字符串的字符数组指针size_t length; // 实际字符个数size_t capacity; // 字符数组容量public:MyString(); // 默认构造函数MyString(const char* str); // 用 C 风格字符串初始化的构造函数MyString(const MyString& other); // 拷贝构造函数~MyString(); // 析构函数size_t size() const;int compare(const MyString& other) const;MyString& append(const char* str);MyString& insert(size_t pos, const char* str);MyString& erase(size_t pos, size_t count);MyString operator+(const MyString& other) const;char& operator[](size_t index);const char& operator[](size_t index) const;MyString& operator=(const MyString& other);
};
👇解释:
- 这里定义了 MyString 类,有存储字符串的 data 指针、记录长度的 length 和容量的 capacity。还有各种函数用于不同操作。
2.构造函数实现
2.1 默认构造函数
MyString::MyString() : data(nullptr), length(0), capacity(0) {}
创建空字符串,data 设为 nullptr,长度和容量都为 0。
2.2 用 C 风格字符串初始化的构造函数
MyString::MyString(const char* str) {if (str == nullptr) {data = nullptr;length = 0;capacity = 0;return;}length = strlen(str); // 获取传入字符串的长度capacity = length;data = new char[capacity + 1]; // 分配足够的内存空间strcpy(data, str); // 复制字符串到 data 所指向的数组
}
👀从 C 风格字符串初始化。若传入 nullptr,创建空字符串。否则,获取长度设为 length 和 capacity,分配内存并复制字符串到 data。
2.3 拷贝构造函数
MyString::MyString(const MyString& other) {length = other.length; // 设置新对象的长度capacity = other.capacity; // 设置新对象的容量data = new char[capacity + 1]; // 分配内存strcpy(data, other.data); // 复制字符串
}
👀创建新对象,内容与传入对象相同。设置长度和容量,分配内存并复制字符串。
3. 析构函数实现
MyString::~MyString() {if (data!= nullptr) {delete[] data; // 释放内存}
}
👀释放 data 指向的内存,避免内存泄漏。
4.获取字符串长度函数
size_t MyString::size() const {return length; // 返回字符串长度
}
👀直接返回字符串长度 length。
5.字符串比较函数
int MyString::compare(const MyString& other) const {for (size_t i = 0; i < length && i < other.length; i++) {if (data[i]!= other.data[i]) {return data[i] < other.data[i]? -1 : 1;}}if (length < other.length) {return -1;} else if (length > other.length) {return 1;}return 0;
}
👀逐字符比较两个字符串,先比较字符,再比较长度,返回相应结果。
6.字符串连接函数
MyString& MyString::append(const char* str) {if (str == nullptr) {return *this; // 传入为空则直接返回当前对象}size_t strLen = strlen(str); // 计算要添加的字符串长度if (length + strLen > capacity) {reserve(length + strLen); // 检查容量,不够则扩展}strcpy(data + length, str); // 将字符串添加到当前字符串末尾length += strLen; // 更新长度return *this;
}
👇解释:
👀在末尾添加字符串。若传入 nullptr,返回当前对象。否则,检查容量,不够就扩展,然后复制字符串并更新长度。
7.字符串插入函数
MyString& MyString::insert(size_t pos, const char* str) {if (str == nullptr) {return *this; // 传入为空则直接返回当前对象}size_t strLen = strlen(str); // 计算要插入的字符串长度if (length + strLen > capacity) {reserve(length + strLen); // 检查容量,不够则扩展}for (size_t i = length; i > pos; i--) {data[i + strLen - 1] = data[i - 1]; // 移动字符腾出空间}for (size_t i = 0; i < strLen; i++) {data[pos + i] = str[i]; // 复制要插入的字符串}length += strLen; // 更新长度return *this;
}
👇解释:
🔥🔥🔥 在指定位置插入字符串。若传入 nullptr,返回当前对象。检查容量,不够就扩展,移动字符腾出空间,复制字符串并更新长度。
8.字符串删除函数
MyString& MyString::erase(size_t pos, size_t count) {if (pos >= length) {return *this; // 位置不合法则返回当前对象}if (pos + count > length) {count = length - pos; // 调整要删除的长度}for (size_t i = pos; i < length - count; i++) {data[i] = data[i + count]; // 移动字符填补空缺}length -= count; // 更新长度return *this;
}
👇解释:
🔥🔥🔥 删除指定位置和长度的字符串。若位置不合法,返回当前对象。调整要删除的长度,移动字符填补空缺并更新长度。
9.字符串加法操作符重载
MyString MyString::operator+(const MyString& other) const {MyString result;result.length = length + other.length; // 设置新对象长度result.capacity = result.length;result.data = new char[result.capacity + 1]; // 分配内存strcpy(result.data, data); // 复制第一个字符串strcpy(result.data + length, other.data); // 复制第二个字符串return result;
}
👇解释:
🔥🔥🔥 重载加法操作符,创建新对象,长度为两字符串长度之和,分配内存,复制两个字符串到新对象并返回。
10.下标操作符重载
char& MyString::operator[](size_t index) {return data[index]; // 返回非 const 对象的字符引用,可以修改
}
const char& MyString::operator[](size_t index) const {return data[index]; // 返回 const 对象的字符引用,只能读取
}
🔥🔥🔥 重载下标操作符,可通过下标访问字符串字符,非 const 对象可修改,const 对象只能读取。
11.赋值操作符重载
MyString& MyString::operator=(const MyString& other) {if (this!= &other) {if (data!= nullptr) {delete[] data; // 释放当前对象内存}length = other.length; // 复制长度capacity = other.capacity;data = new char[capacity + 1]; // 分配新内存strcpy(data, other.data); // 复制字符串}return *this;
}
👇解释:
👀重载赋值操作符,若不是自我赋值,释放当前对象内存,复制长度、容量和字符串数据并返回。
💯内存管理相关函数(如reserve
和resize
)
1.reserve
函数
void MyString::reserve(size_t new_capacity) {if (new_capacity > capacity) {char* new_data = new char[new_capacity + 1]; // 分配新内存if (data!= nullptr) {strcpy(new_data, data); // 复制原字符串delete[] data; // 释放原内存}data = new_data; // 更新 data 指针capacity = new_capacity; // 更新容量}
}
👀 扩展字符串容量。若新容量大于当前容量,分配新内存,复制原字符串,释放原内存,更新 data 和 capacity。
2.resize
函数
void MyString::resize(size_t new_length, char fill_char = '\0') {if (new_length > length) {if (new_length > capacity) {reserve(new_length); // 检查容量,不够则扩展}for (size_t i = length; i < new_length; i++) {data[i] = fill_char; // 用填充字符填充新增部分}} else if (new_length < length) {length = new_length; // 截断字符串data[length] = '\0';}
}
👀 调整字符串长度。若新长度大于当前长度,检查容量,不够就扩展,用填充字符填充新增部分。若新长度小于当前长度,截断字符串并更新长度。
💯示例用法
✍ 以下是一个简单的
main
函数示例,展示如何使用模拟实现的MyString
类:
int main() {MyString str1("Hello");MyString str2(" World");// 使用 append 函数str1.append(str2.data);std::cout << "After append: " << str1.data << std::endl;// 使用 insert 函数str1.insert(5, "Beautiful ");std::cout << "After insert: " << str1.data << std::endl;// 使用 erase 函数str1.erase(5, 10);std::cout << "After erase: " << str1.data << std::endl;// 使用 operator+ 重载MyString str3 = str1 + "!";std::cout << "After + operator: " << str3.data << std::endl;return 0;
}
💯总结
🍎通过模拟实现 string 类,我们了解了字符串处理原理和技术。
从存储结构到操作函数,再到内存管理,每个环节都重要。这有助于理解标准库的 string 类,提高处理字符串问题的能力,✌为编写更好的代码打基础。
以后我将深入研究继承、多态、模板等特性,并将默认成员函数与这些特性结合,以解决更复杂编程问题!欢迎关注我👉【A Charmer】