赞
踩
本文只是对部分函数进行分析和代码展示,具体代码我已经上传到GitHub上面了
GitHub链接:https://github.com/Sveter/CPlusPlus
- string是表示字符串的字符串类
- 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
- string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>string;
- 不能操作多字节或者变长字符的序列。
#ifndef __STRING_H__ #define __STRING_H__ #include <iostream> #include <string.h> unsig namespace std; class String { //为了实现迭代器 public: typedef char* Iterator; public: //默认成员函数 //构造函数以及构造函数的重载 String() {} String(const char* str) { if (nullptr == str) { str = ""; } _size = strlen(str); _str = new char[_size + 1]; _capacity = _size; strcpy(_str, str); } String(const char* str, size_t size) { if (size < 0) { cout << "size error" <<endl; exit(EXIT_SUCCESS); } _size = size; _str = new char[_size + 1]; _capacity = _size; strncpy(_str, str, size); if (size < strlen(str)) { _str[_size] = 0; } } //拷贝构造函数 //采用深拷贝的传统写法 String(const String& s) :_str(new char[s._capacity+1]) ,_capacity(s._capacity) ,_size(s._size) { strcpy(_str, s._str); } //深拷贝的现代版写法 //String(const String& s) //{ // String strTmp(s._str); // swap(_str, strTmp); //} //赋值运算符的重载 String& operator=(const String& s) { if (&s != this) { char* pStr = new char[s._capacity + 1]; strcpy(pStr, s._str); delete[] _str; _str = pStr; _size = s._size; _capacity = s._capacity; } return *this; } //析构函数 ~String() { if (_str) { delete[] _str; _str = nullptr; _capacity = 0; _size = 0; } } //成员函数 //1. 迭代器 Iterator Begin(); Iterator End(); //反向查找 Iterator RBegin(); Iterator REnd(); //2. 增删改查 void PushBack(char c); //尾插字符 void Append(const char* str); //追加字符串 String& Insert(size_t pos, char c); //在指定位置插入字符 String& Insert(size_t pos, const char* str); //在指定位置插入字符串 String& Erase(size_t pos, size_t len); //删除指定位置,指定长度的内容 void Resize(size_t newSize, char c = '0'); //调整大小 void Reserve(size_t newCapacity); //扩容 int Size()const; //查询字符串大小 int Capacity()const; //查询容量 bool Empty()const; //判断是否为空 void Clear(); //清空 int Find(char c, size_t pos = 0); //查找字符第一次出现的位置 int rFind(char c); //从后往前查找字符第一次出现的位置 void Swap(String& s); //字符串交换 String SubStr(size_t pos, size_t size); //截取字符串 const char* C_Str()const; //以C的形式输出 //3. []的重载 char& operator[](size_t index); const char& operator[](size_t index)const; //4. 运算符的重载 bool operator<(const String& s); bool operator<=(const String& s); bool operator>(const String& s); bool operator>=(const String& s); bool operator==(const String& s); bool operator!=(const String& s); String operator+(char c); //+符号的重载 String operator+(const char* str) String operator+=(char c) //+=符号的重载 String operator+=(const char* str) //<<&>>的重载 friend ostream& operator<<(ostream& _cout, const String& s) friend istream& operator>>(istream& _cin, String& s) private: char* _str; size_t _capacity; size_t _size; //find函数没找到的返回值 const static int npos; }; const int String::npos = -1; #endif //!__STRING_H__
在这里我仅对部分成员函数分析
1. 构造函数和拷贝构造函数
- 构造函数是创建一个对象,然后给_str变量申请内存,再设置好_size和_capacity变量
- 拷贝构造函数这里分为浅拷贝和深拷贝,我们用深拷贝,在编译器中默认是浅拷贝,最终导致的问题是,共用同一块内存空间,在释放时同一块空间被释放多次而引起程序崩溃
浅拷贝和深拷贝
赋值运算符重载和拷贝构造函数存在同样的问题,在这里我们用的也是深拷贝的方式
- 先判断是否需要扩容
- 把pos位置之后的字符都向后挪一位,在pos位置插入指定字符
String& Insert(size_t pos, char c)
{
if (_size + 1 >= _capacity)
{
Reserve(_capacity * 2);
}
_str[_size + 1] = '\0';
for (int i = _size; i > pos; i--)
{
_str[i] = _str[i - 1];
}
_str[pos] = c;
++_size;
return *this;
}
第一种,pos位置之后的字符个数大于n,pos之后全删
第二种,pos位置之后的字符个数小于n,则我们需要在pos之后删除n个元素
String& Erase(size_t pos, size_t len) { //删除的数据未超过字符串长度 if (pos + len <= _size) { while (_str[pos + len] != '\0') { _str[pos] = _str[pos + len]; pos++; } _str[pos] = _str[pos + len]; _size = strlen(_str); } else { _str[pos] = _str[_size]; _size = strlen(_str); } return *this; }
void TestString1() { String s1; String s2("hello world"); String s3(s2); s1 = s3; cout << s1 << endl; cout << s2 << endl; cout << s3 << endl; } void TestString2() { String s1("hello"); s1.PushBack(' '); s1.PushBack('1'); s1.Append("31"); s1 += '4'; cout << s1 << endl; cout << s1.Size() << endl; cout << s1.Capacity() << endl; // 利用迭代器打印string中的元素 auto it = s1.Begin(); while (it != s1.End()) { cout << *it++; } cout << endl; String s2("hello world!!!"); s1.Swap(s2); cout << s1 << endl; cout << s2 << endl; } void TestString3() { String s("hello"); cout << s << endl; cout << s.Size() << endl; cout << s.Capacity() << endl; s.Resize(10, 'a'); cout << s << endl; cout << s.Size() << endl; cout << s.Capacity() << endl; s.Resize(20); cout << s << endl; cout << s.Size() << endl; cout << s.Capacity() << endl; s.Resize(5); cout << s << endl; cout << s.Size() << endl; cout << s.Capacity() << endl; s.Reserve(50); cout << s << endl; cout << s.Size() << endl; cout << s.Capacity() << endl; } void TestString4() { String s1("abcdefg"); String s2 = s1; cout << s1 << endl; s1.Insert(2, 'h'); cout << s1 << endl; s1.Insert(2, "123"); cout << s1 << endl; s2.Erase(2, 5); cout << s2 << endl; } void TestString5() { String s1 = "abcdef"; String s2 = "abcdh"; cout << (s1 < s2) << endl; cout << (s1 > s2) << endl; cout << (s1 == s2) << endl; cout << (s1 != s2) << endl; cout << (s1 >= s2) << endl; cout << (s1 <= s2) << endl; } int main() { cout << "Test1: 默认成员函数" << endl; TestString1(); cout << endl; cout << "Test2: Iterators + Modifiers" << endl; TestString2(); cout << endl; cout << "Test3: Capacity" << endl; TestString3(); cout << endl; cout << "Test4: Modifiers" << endl; TestString4(); cout << endl; cout << "Test5: 比较" << endl; TestString5(); cout << endl; return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。