手写CString类
- 学习和理解字符串处理机制:手写
CString
类是深入学习字符串处理和内存管理的有效方式。通过实现构造函数、析构函数、赋值运算符等,能够理解字符串在内存中的存储方式、动态内存分配和释放的原理,以及如何处理字符串的复制、拼接、查找等操作。这有助于掌握基本的编程概念和内存管理技巧,提升编程能力。 - 性能优化:标准库中的字符串类(如
std::string
)虽然功能丰富,但在某些特定场景下可能存在性能瓶颈。自己手写CString
类可以根据具体需求进行性能优化。例如,在处理大量短小字符串时,可以采用不同的内存管理策略,避免频繁的内存分配和释放,从而提高程序的运行效率。 - 内存控制:手写
CString
类能够更精确地控制内存的使用。可以根据实际需求选择合适的内存分配方式,避免不必要的内存浪费。例如,在内存有限的嵌入式系统中,自己实现字符串类可以更好地管理内存,确保系统的稳定性和性能。 - 兼容性和跨平台性:在一些特定的开发场景中,可能需要与旧的代码库或特定的平台进行兼容。自己实现
CString
类可以根据具体的兼容性需求进行设计,确保在不同的平台和环境中都能正常工作。例如,在一些不支持标准库的平台上,手写CString
类可以提供基本的字符串处理功能。 - 定制化需求:标准库中的字符串类可能无法满足某些特定的定制化需求。自己手写
CString
类可以根据具体的业务逻辑进行定制。例如,在处理特定格式的字符串时,可以在自定义的CString
类中添加相应的处理方法,提高代码的针对性和效率。 - 深入理解语言特性:手写
CString
类可以深入理解 C++ 语言的特性,如运算符重载、异常处理、模板等。通过实现CString
类,可以更好地掌握这些特性的使用方法,提高对 C++ 语言的理解和运用能力。 - 代码可读性和可维护性:对于一些小型项目或特定的代码模块,手写
CString
类可以使代码更加简洁和易读。可以根据项目的实际情况,设计出符合项目风格的字符串类,提高代码的可维护性。
一、基本功能
1. 构造与析构
cpp
CString(); // 默认构造空字符串
CString(const CString& src); // 拷贝构造
CString(const char* lpsz); // 从C风格字符串构造
CString(char ch); // 从单个字符构造
~CString(); // 析构函数
2. 赋值操作
cpp
CString& operator=(char ch); // 字符赋值
CString& operator=(const char* lpsz); // C风格字符串赋值
CString& operator=(const CString& src); // CString赋值
3. 字符串信息
cpp
int GetLength() const; // 获取字符串长度(不含终止符)
bool IsEmpty() const; // 判断是否为空字符串
void Empty(); // 清空字符串内容
4. 字符访问
cpp
char GetAt(int iIndex); // 获取指定位置字符
void SetAt(int iIndex, char ch); // 修改指定位置字符
char& operator[](int iIndex); // 重载[]运算符(可修改)
const char& operator[](int iIndex) const; // 常量版本
二、字符串操作
1. 查找功能
cpp
int Find(char ch) const; // 查找字符首次出现位置
int Find(char ch, int nStart) const; // 从nStart开始查找字符
int Find(const char* lpszSub) const; // 查找子字符串
int Find(const CString& sSub) const; // 查找CString对象
int ReverseFind(char ch) const; // 查找字符最后一次出现位置
int FindOneOf(char* lpszCharSet) const; // 查找字符集中任意字符首次出现位置
2. 修改功能
cpp
int Replace(char chOld, char chNew); // 替换所有指定字符
int Replace(char* lpszOld, char* lpszNew); // 替换所有子字符串
int Remove(char ch); // 删除所有指定字符
int Insert(int nIndex, char ch); // 在指定位置插入字符
int Insert(int nIndex, char* lpsz); // 在指定位置插入字符串
int Delete(int nIndex, int nCount = 1); // 删除指定范围字符
3. 子串操作
cpp
CString Left(int nCount) const; // 截取左边n个字符
CString Right(int nCount) const; // 截取右边n个字符
CString Mid(int nFirst) const; // 从nFirst到末尾的子串
CString Mid(int nFirst, int nCount) const; // 从nFirst开始截取nCount个字符
4. 大小写与空白处理
cpp
void MakeUpper(); // 转换为大写
void MakeLower(); // 转换为小写
void TrimLeft(); // 去除左侧空白字符
void TrimRight(); // 去除右侧空白字符
void Trim(); // 去除两侧空白字符
5. 其他操作
cpp
CString& MakeReverse(); // 反转字符串
int Format(const char* pstrFormat, ...); // 格式化字符串(类似sprintf)
char* GetBuffer(int nMinBufLength); // 获取内部缓冲区指针
三、运算符重载
1. 连接运算符
cpp
CString& operator+=(char ch); // 追加字符
CString& operator+=(const char* str); // 追加C风格字符串
CString& operator+=(const CString& Str); // 追加CString对象
friend CString operator+(const CString& s1, const CString& s2); // 连接两个CString
friend CString operator+(const CString& s1, char ch); // 连接CString和字符
friend CString operator+(const CString& s1, char* ch); // 连接CString和C风格字符串
2. 比较运算符
cpp
friend bool operator==(const CString& s1, const CString& s2); // 判断两个CString是否相等
friend bool operator!=(const CString& s1, const CString& s2); // 判断两个CString是否不等
friend bool operator>(const CString& s1, const CString& s2); // 比较大小(字典序)
friend bool operator<(const CString& s1, const CString& s2); // 比较大小
friend bool operator>=(const CString& s1, const CString& s2); // 比较大小
friend bool operator<=(const CString& s1, const CString& s2); // 比较大小
四、使用示例
1. 基本操作
cpp
CString str1("Hello"); // 从C风格字符串构造
CString str2('A'); // 从字符构造
str1 += " World"; // 追加字符串
str2.MakeUpper(); // 转换为大写
int len = str1.GetLength(); // 获取长度
2. 查找与替换
cpp
int pos = str1.Find("World"); // 查找子串
str1.Replace("World", "C++"); // 替换子串
str1.Remove('l'); // 删除所有 'l'
3. 子串操作
cpp
CString left = str1.Left(5); // "Hello"
CString mid = str1.Mid(6, 3); // "C++"
4. 格式化
cpp
CString formatted;
formatted.Format("Value: %d, Name: %s", 42, "John"); // "Value: 42, Name: John"
测试用例
源码下载:一个自定义的CString类,用于处理字符串它模拟了类似MFC中CString的功能,提供了丰富的字符串操作接口,涵盖了构造、赋值、追加、比较、截取、查找、大小换以及空白字符处理等操作资源-CSDN文库
void TestCString()
{printf("开始测试 CString 类...\n");// ===== 构造函数测试 =====printf("测试构造函数...\n");CString s1; // 默认构造assert(s1.GetLength() == 0);assert(s1.IsEmpty());CString s2("Hello"); // C风格字符串构造assert(s2.GetLength() == 5);assert(!s2.IsEmpty());assert(s2[0] == 'H');CString s3('A'); // 字符构造assert(s3.GetLength() == 1);assert(s3[0] == 'A');CString s4(s2); // 拷贝构造assert(s4.GetLength() == 5);assert(s4[0] == 'H');// ===== 基本操作测试 =====printf("测试基本操作...\n");s1 = "World"; // 赋值运算符assert(s1.GetLength() == 5);assert(s1[0] == 'W');s1 += '!'; // 追加字符assert(s1.GetLength() == 6);assert(s1[5] == '!');s1 += " Test"; // 追加C风格字符串assert(s1.GetLength() == 11);assert(s1[6] == ' ');s1 += s2; // 追加CStringassert(s1.GetLength() == 16);assert(s1[11] == 'H');s1.SetAt(0, 'w'); // 修改指定位置字符assert(s1[0] == 'w');// ===== 查找测试 =====printf("测试查找功能...\n");assert(s2.Find('e') == 1); // 查找字符assert(s2.Find("ll") == 2); // 查找子串assert(s2.Find('l', 3) == 3); // 从指定位置查找assert(s2.ReverseFind('l') == 3); // 反向查找assert(s2.FindOneOf("aeiou") == 1); // 查找任意字符// ===== 子串测试 =====printf("测试子串功能...\n");assert(s2.Left(2) == "He"); // 左侧子串assert(s2.Right(3) == "llo"); // 右侧子串assert(s2.Mid(1) == "ello"); // 从指定位置到末尾assert(s2.Mid(1, 2) == "el"); // 从指定位置开始的指定长度// ===== 转换测试 =====printf("测试字符串转换...\n");CString s5("Hello");s5.MakeUpper();assert(s5 == "HELLO");//大写转换s5.MakeLower();assert(s5 == "hello");//小写转换s5.MakeReverse();assert(s5 == "olleh");//反转// ===== 修剪测试 =====printf("测试字符串修剪...\n");CString s6(" \tHello World \n");s6.TrimLeft();assert(s6 == "Hello World \n");s6.TrimRight();assert(s6 == "Hello World");s6 = " \t \n";s6.Trim();assert(s6.IsEmpty());// ===== 插入与删除测试 =====printf("测试插入与删除...\n");CString s7("Hello");s7.Insert(1, 'a'); // 插入字符assert(s7 == "Haello");s7.Insert(3, "xx"); // 插入字符串assert(s7 == "Haexxllo");s7.Delete(3, 2); // 删除指定范围assert(s7 == "Haello");s7.Remove('l'); // 删除所有指定字符assert(s7 == "Haeo");// ===== 替换测试 =====printf("测试替换功能...\n");CString s8("Hello");s8.Replace('l', 'x'); // 替换字符assert(s8 == "Hexxo");s8.Replace("xx", "ll"); // 替换字符串assert(s8 == "Hello");// ===== 格式化测试 =====printf("测试字符串格式化...\n");CString s9;s9.Format("%d + %d = %d", 1, 2, 3);assert(s9 == "1 + 2 = 3");// ===== 比较测试 =====printf("测试字符串比较...\n");CString s10("abc");CString s11("abd");assert(s10 < s11);assert(s10 <= s11);assert(s11 > s10);assert(s11 >= s10);assert((s10 == s11) == false);assert((s10 != s11) == true);// ===== 缓冲区测试 =====printf("测试缓冲区操作...\n");// 测试用例 1: 正常情况CString str("HelloWorld");const char* buffer = str.GetBuffer(5);assert(buffer != nullptr);assert(strcmp(buffer, "World") == 0);printf("所有测试通过!\n");
}