网站更新 缓存,星子网,金融学类就业方向及就业前景,少儿编程加盟费一般多少嘿嘿,家人们,今天咱们来模拟实现string,好啦,废话不多讲,开干! 1:string.h
1.1:构造函数与拷贝构造函数
1.1.1:写法一
1.1.2:写法二(给缺省值)
1.2:赋值运算符重载与operatror[]获取元素
1.3:容量与迭代器
1.4:reserve与resize
1.5:清空与判断是否为空
1.6:push_back与…嘿嘿,家人们,今天咱们来模拟实现string,好啦,废话不多讲,开干! 1:string.h
1.1:构造函数与拷贝构造函数
1.1.1:写法一
1.1.2:写法二(给缺省值)
1.2:赋值运算符重载与operatror[]获取元素
1.3:容量与迭代器
1.4:reserve与resize
1.5:清空与判断是否为空
1.6:push_back与append
1.7:insert
1.7.1:插入字符
1.7.2:插入字符串
1.8:erase
1.9:operator
1.9.1:添加字符
1.9.2:添加字符串
1.91:find
1.91.1:查找字符
1.91.2:查找字符串
1.92:substr与swap
1.93:非成员函数的重载
1.93.1:流插入与流提取的重载
1.93.2:其他非成员函数的重载
2:Test.cpp
2.1:构造函数与拷贝构造
2.1.1:测试写法一
2.1.2:测试写法二
2.2:测试赋值运算符重载与[]获取元素
2.3:测试迭代器与容量
2.4:测试reserve与resize
2.4.1:测试resize
2.4.2:测试reserve
2.5:测试push_back与append
2.6:测试insert
2.6.1:测试插入字符
2.6.2:测试插入字符串
2.7:测试erase
2.8:测试operator
2.9:测试find
2.91:测试substr与swap
2.92:测试流插入与流提取
2.92.1:第一版流提取
2.92.2:第二版流提取
2.93:测试其他非成员函数
3:知识补充
3.1:深拷贝与浅拷贝
3.1.1:浅拷贝
3.1.2:深拷贝
4:总代码
4.1:string.h
4.2:Test.cpp 1:string.h
1.1:构造函数与拷贝构造函数
1.1.1:写法一
#include iostream
#include string.h
#include assert.h
using namespace std;//避免与库中的string冲突,因此使用命名空间
namespace MyString
{class string{public:string():_str(new char[1]), _size(0),_capacity(0){//空字符串只有\0,_str[0] \0;}//构造非空字符串string(const char * str)//开辟空间,多开辟个空间存放\0:_str(new char[strlen(str) 1]){//开辟空间_capacity _size strlen(str);//拷贝数据strcpy(_str, str);}//拷贝构造函数//s2(s1),使用s1拷贝构造s2string(string s){//开辟空间char* temp new char[s._capacity 1];_str temp;_capacity s._capacity;_size s._size;//拷贝数据strcpy(_str, s._str);}//析构函数~string(){delete[] _str;_size _capacity 0;}private://定义成员变量并且给缺省值char* _str;int _size;int _capacity;};}1.1.2:写法二(给缺省值)
#include iostream
#include string.h
#include assert.h
using namespace std;//避免与库中的string冲突,因此使用命名空间
namespace MyString
{class string{public://string()// :_str(new char[1])// , _size(0)// ,_capacity(0)//{// //空字符串只有\0,// _str[0] \0;//}构造非空字符串//string(const char * str)// //开辟空间,多开辟个空间存放\0// :_str(new char[strlen(str) 1])//{// //开辟空间// _capacity _size strlen(str);// //拷贝数据// strcpy(_str, str);//}//给缺省值,构造空字符串时使用缺省值string(const char* str )//开辟空间,多开辟个空间存放\0:_str(new char[strlen(str) 1]){//开辟空间_capacity _size strlen(str);//拷贝数据strcpy(_str, str);}/*拷贝构造函数s2(s1),使用s1拷贝构造s2*/string(string s){//开辟空间char* temp new char[s._capacity 1];_str temp;_capacity s._capacity;_size s._size;//拷贝数据strcpy(_str, s._str);}//析构函数~string(){delete[] _str;_size _capacity 0;}private://定义成员变量并且给缺省值char* _str nullptr;int _size 0;int _capacity 0;};}1.2:赋值运算符重载与operatror[]获取元素 //s1 s2 this----s1 s2-----s//赋值运算符重载string operator (string s){//开辟新空间char * temp new char[s._capacity 1];//释放旧空间delete _str;//拷贝数据strcpy(temp, s._str);//指向新空间_str temp;_size s._size;_capacity s._capacity;return *this;}//T ,返回引用同样可以提高效率,有返回值的目的是为了支持连续赋值.char operator[](size_t position){assert(position _size);return _str[position];}//const成员函数,给const对象调用,与上面构成函数重载const char operator[](size_t position) const{assert(position _size);return _str[position];} 1.3:容量与迭代器 迭代器呢其实是一个类指针,因此我们在模拟实现的时候,直接通过指针来进行模拟即可~ #include iostream
#include string.h
#include assert.h
using namespace std;//避免与库中的string冲突,因此使用命名空间
namespace MyString
{class string{typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str _size;}//设置成员函数const_iterator begin() const{return _str;}const_iterator end() const{return _str _size;}//capacitysize_t size(){return _size;}size_t capacity(){return _capacity;}private://定义成员变量并且给缺省值char* _str nullptr;int _size 0;int _capacity 0;};}1.4:reserve与resize
我们来回顾下reserve与resize的相关知识 1:reserve 比size小不变化比size大但小于capacity也不发生变化 比capacity大才会进行扩容 因此我们只要判断是否比capacity大 2:resize 比size小则进行删除. 比size大但小于capacity会改变size,并用\0插入. 比capacity大,会先改变size的大小同时进行扩容. //仅需判断是否比capacity大void reserve(size_t n){if(n _capacity){//开辟新空间char* temp new char[n 1];//拷贝数据strcpy(temp, _str);//释放旧空间delete[] _str;//指向新空间_str temp;_capacity n;}}void resize(size_t n,char ch \0){//比size小则会进行删除if (n _size){_str[n] ch;}//比size大比capacity小会改变size,并且用\0插入else if( n _size n _capacity){_size n;}//比capacity大, 会先改变size的大小同时进行扩容.else{//扩容reserve(n);for(size_t i _size; i _capacity ; i){_str[i] ch;}_size n;}}
1.5:清空与判断是否为空 //只清除有效字符,不改变底层空间void clear(){_str[0] \0;_size 0;}bool empty()const{return _size 0;} 这里博主就不带着uu们测试啦,感兴趣的uu可以自己下去测试下~ 1.6:push_back与append
//Modifiersvoid push_back(char ch){//检查容量if (_size _capacity)//二倍扩容reserve(_capacity 0 ? 4 : 2 * _capacity);_str[_size] ch;_size;_str[_size] \0;}void append(const char * str){assert(str);//求出添加的字符串的长度int length strlen(str);//判断添加后的有效字符数量是否越过容量if (_size length _capacity)reserve(_size length);//_str _size的位置为\0strcpy(_str _size, str);_size length;} 1.7:insert
1.7.1:插入字符 string insert(size_t position,char ch){assert(position _size);if (_size _capacity)//二倍扩容reserve(_capacity 0 ? 4 : 2 * _capacity);//从后向前挪动覆盖for(int i _size - 1; i position ;i--){_str[i 1] _str[i];}_str[position] ch;_size;_str[_size] \0;return *this;}
1.7.2:插入字符串
string insert(size_t position,const char * str){assert(position _size);int length strlen(str);if (_size length _capacity)reserve(_size length);//从后向前挪动覆盖//_size length - 1表示挪动的字符串的重点,positon length表示挪动的字符串的起点for(int i _size length - 1; i position length; i--){_str[i] _str[i - length];}//拷贝数据strncpy(_str position, str, length);_size length;_str[_size] \0;return *this;} 1.8:erase void erase(size_t position 0,size_t len -1){//防止越界assert(position _size);//len -1如果 len 为 -1表示删除到字符串末尾。//len _size - pos,如果 len 超过从 pos 开始的剩余字符长度同样认为是删除到末尾。if(len -1 || len _size - position){_str[position] \0;_size position;}else{//将 pos len 后的字符串内容复制到 pos 位置从而覆盖中间 len 长度的字符实现删除操作strcpy(_str position, _str position len);}} 1.9:operator
1.9.1:添加字符 string operator(char ch){push_back(ch);return *this;}1.9.2:添加字符串 string operator(const char * str){append(str);return *this;}
1.91:find
1.91.1:查找字符
//添加const修饰,令const成员与非const成员均可调用size_t find(char ch, size_t pos 0) const{for(size_t i pos; i _size;i){if (_str[i] ch)return i;}return -1;}
1.91.2:查找字符串 const char * c_str()const{return _str;}//添加const修饰,令const成员与非const成员均可调用size_t find(const char * str,size_t pos 0 )const{const char* p strstr(_str pos, str);if(p ! NULL){//指针 - 指针得到对应的首字符下标return p - _str;}return -1;}
1.92:substr与swap string substr(size_t pos 0, size_t len -1){string substr;//len -1如果 len 为 -1表示全部获取。//len _size - pos,如果 len 超过从 pos 开始的剩余字符长度,同样认为是全部获取if(len _size - pos || len -1){for(size_t i 0; i _size; i){substr _str[i];}}else{for(size_t i pos; i pos len;i){substr _str[i];}}return substr;}//s1.swap(s2)void swap(string str){std::swap(_str, str._str);std::swap(_size, str._size);std::swap(_capacity, str._capacity);}1.93:非成员函数的重载
1.93.1:流插入与流提取的重载 ostream operator(ostream _cout,MyString::string str){for (auto ch : str){cout ch;}return _cout;}istream operator(istream _cin, MyString::string str){第一版:会导致空间的浪费//char ch;_cin是无法读到\n与 的//ch _cin.get();清空字符//str.clear();//while (ch ! \n ch ! )//{// str ch;// ch _cin.get();//}//return _cin;//第二版char ch;ch _cin.get();//底层给个buffchar buff[128];size_t i 0;//将原本的字符清空str.clear();//cin无法读取 与\nwhile (ch ! \n ch ! ){buff[i] ch;//最后一个字符设置为\0if(i 127){buff[i] \0;str buff;}//持续读取字符ch _cin.get();}if(i 0){buff[i] \0;str buff;}return _cin;}
}按照常规方式,流提取按照上面的第一版方式进行重载即可,但是,底层其实是给了buff,目的是: 防止空间的浪费,因为按照常规方式重载的话,那么在 扩容的时候一般是1.5倍或者2倍扩容,而通过给一个buff,能够最大程度地防止空间的浪费. 1.93.2:其他非成员函数的重载 //会先调用此swap,有现成的,吃现成的,不使用模版里面的swapvoid swap(string x, string y){x.swap(y);}//自定义类型传值传参会调用拷贝构造,因此需要传引用bool operator(const MyString::string str1, const MyString::string str2){int result strcmp(str1.c_str(), str2.c_str());return result 0;}bool operator(const MyString::string str1, const MyString::string str2){int result strcmp(str1.c_str(), str2.c_str());return result 0;}bool operator(const MyString::string str1, const MyString::string str2){int result strcmp(str1.c_str(), str2.c_str());return result 0;}bool operator(const MyString::string str1, const MyString::string str2){return (str1 str2) || (str1 str2);}bool operator(const MyString::string str1, const MyString::string str2){return !(str1 str2);}bool operator!(const MyString::string str1, const MyString::string str2){return !(str1 str2);}
2:Test.cpp
2.1:构造函数与拷贝构造
2.1.1:测试写法一
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestConstructionAndCopyConstruction()
{MyString::string s1;MyString::string s2(hello world);MyString::string s3(s2);
}
int main()
{TestConstructionAndCopyConstruction();return 0;
} 2.1.2:测试写法二
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestConstructionAndCopyConstruction()
{MyString::string s1;MyString::string s2(hello world);MyString::string s3(s2);
}
int main()
{TestConstructionAndCopyConstruction();return 0;
} 2.2:测试赋值运算符重载与[]获取元素
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestAssignmentOperatorOverloadingAndElementAccess()
{MyString::string s1;MyString::string s2(hello world);const MyString::string s3(hello Linux);s1 s2;cout s1[0]: s1[0] endl;cout s3[6]: s3[6] endl;
}
int main()
{TestAssignmentOperatorOverloadingAndElementAccess();return 0;
} 2.3:测试迭代器与容量
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestIteratorAndCapacity()
{MyString::string s1;MyString::string s2(hello world);s1 s2;for(auto element : s2){cout element endl;}cout s2.size() s2.size() endl;cout s2.capacity() s2.capacity() endl;
}int main()
{TestIteratorAndCapacity();return 0;
} 2.4:测试reserve与resize
2.4.1:测试resize #define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestResize()
{MyString::string str(hello world);//比size小则进行删除str.resize(10);cout size: str.size() endl;cout capacity: str.capacity() endl;cout endl;//比size大但小于capacity会用改变size,并用\0插入str.resize(13);cout size: str.size() endl;cout capacity: str.capacity() endl;cout endl;//比capacity大,会先改变size的大小同时进行扩容str.resize(20);cout size: str.size() endl;cout capacity: str.capacity() endl;
}int main()
{TestResize();return 0;
}
2.4.2:测试reserve
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestRserve()
{MyString::string str(hello world);cout size: str.size() endl;cout capacity: str.capacity() endl;cout reserver后 endl;cout endl;//比size小不变化str.reserve(10);cout size: str.size() endl;cout capacity: str.capacity() endl;cout endl;//比size大但小于capacity也不发生变化str.reserve(13);cout size: str.size() endl;cout capacity: str.capacity() endl;cout endl;//比capacity大才会进行扩容str.reserve(20);cout size: str.size() endl;cout capacity: str.capacity() endl;
}int main()
{TestRserve();return 0;
} 2.5:测试push_back与append
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestPushBackAndAppend()
{MyString::string str;str.append(hello world);str.push_back(x);
}int main()
{TestPushBackAndAppend();return 0;
} 2.6:测试insert
2.6.1:测试插入字符
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestInsert()
{MyString::string str(hello world);//在下标为5的位置插入字符hstr.insert(5, h);
}int main()
{TestInsert();return 0;
} 2.6.2:测试插入字符串
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestInsert()
{MyString::string str(hello world);//在下标为5的位置插入字符hstr.insert(5, h);str.insert(2, Linux);
}int main()
{TestInsert();return 0;
} 2.7:测试erase
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestErase()
{MyString::string str(hello world);str.erase(2, 4);
}int main()
{TestErase();return 0;
} 2.8:测试operator
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid Test()
{MyString::string str(hello);str ;str Linux;
}int main()
{Test();return 0;
} 2.9:测试find
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestFind()
{MyString::string str(hello Linux);cout str.find(l, 2) endl;cout str.find(Linux, 2) endl;
}int main()
{TestFind();return 0;
} 2.91:测试substr与swap
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestSwapAndSubstr()
{MyString::string s1(hello Linux);MyString::string s2(hello bit);MyString::string temp s1.substr(6, 5);cout 交换前 endl;cout s1: s1 endl;cout s2: s2 endl;cout temp: temp endl;s1.swap(s2);cout 交换后 endl;cout s1: s1 endl;cout s2: s2 endl;
}
int main()
{TestSwapAndSubstr();return 0;
} 2.92:测试流插入与流提取
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestStreamInsertionAndStreamExtraction()
{MyString::string s1;cin s1;cout s1 endl;cout s1.size: s1.size() endl;cout s1.capacity: s1.capacity() endl;
}
int main()
{TestStreamInsertionAndStreamExtraction();return 0;
}
2.92.1:第一版流提取 2.92.2:第二版流提取 2.93:测试其他非成员函数
#define _CRT_SECURE_NO_WARNINGS
#include String.h
void TestOtherFunction()
{MyString::string s1(hello world);MyString::string s2(hello bit);swap(s1, s2);s1.swap(s2);cout s1.c_str() endl;cout s2.c_str() endl;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()
{TestOtherFunction();return 0;
} 3:知识补充
3.1:深拷贝与浅拷贝
在讲深浅拷贝之前,我们来看一个现象 我们可以清晰地看到,s2与s3的地址一样,这是为什么呢,因为博主将显示定义的拷贝构造函数给屏蔽了,因此在拷贝构造s3时会调用编译器默认的拷贝构造函数,那么这就会导致一个问题: s2与s3共用同一块内存空间,在释放时同一块内存空间被释放多次而会引起程序崩溃,这种方式被称作浅拷贝. 3.1.1:浅拷贝 浅拷贝:又被称作位拷贝,编译器直接是将另外一个对象的值拷贝复制过来.如果对象中管理资源,那么最后就会导致多个对象共享一份资源,当一个对象销毁时就会将资源释放掉,而此时另一些对象不知道该资源已经被释放,以为还是有效的,那么因此当继续对资源进行操作时,就会发生访问违规~ 举一个简单例子 就像一个家庭中有两个孩子,但父母只买了一份玩具两个孩子愿意一块玩则万事大吉万一不想分享就你争我抢,玩具损坏. 那么该如何解决浅拷贝的问题呢,用深拷贝就可以即每个对象都有一份独立的资源不要和其他对象共享。父母给每个孩子都买一份玩具各自玩各自的就不会有存在任何矛盾. 3.1.2:深拷贝 如果一个类中涉及到资源的管理其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出,一般情况都是按照深拷贝方式提供. 4:总代码
4.1:string.h
#include iostream
#include string.h
#include assert.h
using namespace std;//避免与库中的string冲突,因此使用命名空间
namespace MyString
{class string{typedef char* iterator;typedef const char* const_iterator;public://string()// :_str(new char[1])// , _size(0)// ,_capacity(0)//{// //空字符串只有\0,// _str[0] \0;//}构造非空字符串//string(const char * str)// //开辟空间,多开辟个空间存放\0// :_str(new char[strlen(str) 1])//{// //开辟空间// _capacity _size strlen(str);// //拷贝数据// strcpy(_str, str);//}//给缺省值,构造空字符串时使用缺省值string(const char* str )//开辟空间,多开辟个空间存放\0:_str(new char[strlen(str) 1]){//开辟空间_capacity _size strlen(str);//拷贝数据strcpy(_str, str);}/*拷贝构造函数s2(s1),使用s1拷贝构造s2*/string(string s){//开辟空间char* temp new char[s._capacity 1];_str temp;_capacity s._capacity;_size s._size;//拷贝数据strcpy(_str, s._str);}//s1 s2 this----s1 s2-----s//赋值运算符重载string operator (string s){//开辟新空间char* temp new char[s._capacity 1];//释放旧空间delete _str;//拷贝数据strcpy(temp, s._str);//指向新空间_str temp;_size s._size;_capacity s._capacity;return *this;}//T ,返回引用同样可以提高效率,有返回值的目的是为了支持连续赋值.char operator[](size_t position){assert(position _size);return _str[position];}//const成员函数,给const对象调用,与上面构成函数重载const char operator[](size_t position) const{assert(position _size);return _str[position];}/////iteraoriterator begin(){return _str;}iterator end(){return _str _size;}//设置成员函数const_iterator begin() const{return _str;}const_iterator end() const{return _str _size;}//capacitysize_t size(){return _size;}size_t capacity(){return _capacity;}//仅需判断是否比capacity大void reserve(size_t n){if (n _capacity){//开辟新空间char* temp new char[n 1];//拷贝数据strcpy(temp, _str);//释放旧空间delete[] _str;//指向新空间_str temp;_capacity n;}}void resize(size_t n, char ch \0){//比size小则会进行删除if (n _size){_str[n] ch;}//比size大比capacity小会改变size,并且用\0插入else if (n _size n _capacity){_size n;}//比capacity大, 会先改变size的大小同时进行扩容.else{//扩容reserve(n);for (size_t i _size; i _capacity; i){_str[i] ch;}_size n;}}//Modifiersvoid push_back(char ch){//检查容量if (_size _capacity)//二倍扩容reserve(_capacity 0 ? 4 : 2 * _capacity);_str[_size] ch;_size;_str[_size] \0;}void append(const char* str){assert(str);//求出添加的字符串的长度int length strlen(str);//判断添加后的有效字符数量是否越过容量if (_size length _capacity)reserve(_size length);//_str _size的位置为\0strcpy(_str _size, str);_size length;}string insert(size_t position, char ch){assert(position _size);if (_size _capacity)//二倍扩容reserve(_capacity 0 ? 4 : 2 * _capacity);//从后向前挪动覆盖for (int i _size - 1; i position; i--){_str[i 1] _str[i];}_str[position] ch;_size;_str[_size] \0;return *this;}void clear(){_str[0] \0;_size 0;}bool empty()const{return _size 0;}string insert(size_t position, const char* str){assert(position _size);int length strlen(str);if (_size length _capacity)reserve(_size length);//从后向前挪动覆盖//_size length - 1表示挪动的字符串的重点,positon length表示挪动的字符串的起点for (int i _size length - 1; i position length; i--){_str[i] _str[i - length];}//拷贝数据strncpy(_str position, str, length);_size length;_str[_size] \0;return *this;}void erase(size_t position 0, size_t len -1){//防止越界assert(position _size);//len -1如果 len 为 -1表示删除到字符串末尾。//len _size - pos,如果 len 超过从 pos 开始的剩余字符长度同样认为是删除到末尾。if (len -1 || len _size - position){_str[position] \0;_size position;}else{//将 pos len 后的字符串内容复制到 pos 位置从而覆盖中间 len 长度的字符实现删除操作strcpy(_str position, _str position len);}}string operator(char ch){push_back(ch);return *this;}string operator(const char * str){append(str);return *this;}const char * c_str()const{return _str;}//添加const修饰,令const成员与非const成员均可调用size_t find(char ch, size_t pos 0) const{for(size_t i pos; i _size;i){if (_str[i] ch)return i;}return -1;}//添加const修饰,令const成员与非const成员均可调用size_t find(const char * str,size_t pos 0 )const{const char* p strstr(_str pos, str);if(p ! NULL){//指针 - 指针得到对应的首字符下标return p - _str;}return -1;}string substr(size_t pos 0, size_t len -1){string substr;//len -1如果 len 为 -1表示全部获取。//len _size - pos,如果 len 超过从 pos 开始的剩余字符长度,同样认为是全部获取if(len _size - pos || len -1){for(size_t i 0; i _size; i){substr _str[i];}}else{for(size_t i pos; i pos len;i){substr _str[i];}}return substr;}//s1.swap(s2)void swap(string str){std::swap(_str, str._str);std::swap(_size, str._size);std::swap(_capacity, str._capacity);}//析构函数~string(){delete[] _str;_size _capacity 0;}private://定义成员变量并且给缺省值char* _str nullptr;int _size 0;int _capacity 0;};//Non-member_function_overloadsostream operator(ostream _cout,MyString::string str){for (auto ch : str){cout ch;}return _cout;}istream operator(istream _cin, MyString::string str){第一版:会导致空间的浪费//char ch;_cin是无法读到\n与 的//ch _cin.get();清空字符//str.clear();//while (ch ! \n ch ! )//{// str ch;// ch _cin.get();//}//return _cin;//第二版char ch;ch _cin.get();//底层给个buffchar buff[128];size_t i 0;//将原本的字符情况str.clear();//cin无法读取 与\nwhile (ch ! \n ch ! ){buff[i] ch;//最后一个字符设置为\0if(i 127){buff[i] \0;str buff;}//持续读取字符ch _cin.get();}if(i 0){buff[i] \0;str buff;}return _cin;}//会先调用此swap,有现成的,吃现成的,不使用模版里面的swapvoid swap(string x, string y){x.swap(y);}//自定义类型传值传参会调用拷贝构造,因此需要传引用bool operator(const MyString::string str1, const MyString::string str2){int result strcmp(str1.c_str(), str2.c_str());return result 0;}bool operator(const MyString::string str1, const MyString::string str2){int result strcmp(str1.c_str(), str2.c_str());return result 0;}bool operator(const MyString::string str1, const MyString::string str2){int result strcmp(str1.c_str(), str2.c_str());return result 0;}bool operator(const MyString::string str1, const MyString::string str2){return (str1 str2) || (str1 str2);}bool operator(const MyString::string str1, const MyString::string str2){return !(str1 str2);}bool operator!(const MyString::string str1, const MyString::string str2){return !(str1 str2);}
}4.2:Test.cpp
#define _CRT_SECURE_NO_WARNINGS
#include String.hvoid TestConstructionAndCopyConstruction()
{MyString::string s1;MyString::string s2(hello world);MyString::string s3(s2);
}void TestAssignmentOperatorOverloadingAndElementAccess()
{MyString::string s1;MyString::string s2(hello world);const MyString::string s3(hello Linux);s1 s2;cout s1[0]: s1[0] endl;cout s3[6]: s3[6] endl;
}void TestIteratorAndCapacity()
{MyString::string s1;MyString::string s2(hello world);s1 s2;for(auto element : s2){cout element;}cout endl;cout s2.size(): s2.size() endl;cout s2.capacity(): s2.capacity() endl;
}void TestResize()
{MyString::string str(hello world);//比size小则进行删除str.resize(10);cout size: str.size() endl;cout capacity: str.capacity() endl;cout endl;//比size大但小于capacity会用改变size,并用\0插入str.resize(13);cout size: str.size() endl;cout capacity: str.capacity() endl;cout endl;//比capacity大,会先改变size的大小同时进行扩容str.resize(20);cout size: str.size() endl;cout capacity: str.capacity() endl;
}void TestRserve()
{MyString::string str(hello world);cout size: str.size() endl;cout capacity: str.capacity() endl;cout reserver后 endl;cout endl;//比size小不变化str.reserve(10);cout size: str.size() endl;cout capacity: str.capacity() endl;cout endl;//比size大但小于capacity也不发生变化str.reserve(13);cout size: str.size() endl;cout capacity: str.capacity() endl;cout endl;//比capacity大才会进行扩容str.reserve(20);cout size: str.size() endl;cout capacity: str.capacity() endl;
}void TestPushBackAndAppend()
{MyString::string str;str.append(hello world);str.push_back(x);
}
void TestInsert()
{MyString::string str(hello world);//在下标为5的位置插入字符hstr.insert(5, h);str.insert(2, Linux);
}void TestErase()
{MyString::string str(hello world);str.erase(2, 4);
}void Test()
{MyString::string str(hello);str ;str Linux;
}void TestFind()
{MyString::string str(hello Linux);cout str.find(l, 2) endl;cout str.find(Linux, 2) endl;
}
void TestSwapAndSubstr()
{MyString::string s1(hello Linux);MyString::string s2(hello bit);MyString::string temp s1.substr(6, 5);cout 交换前 endl;cout s1: s1 endl;cout s2: s2 endl;cout temp: temp endl;s1.swap(s2);cout 交换后 endl;cout s1: s1 endl;cout s2: s2 endl;
}void TestStreamInsertionAndStreamExtraction()
{MyString::string s1;cin s1;cout s1 endl;cout s1.size: s1.size() endl;cout s1.capacity: s1.capacity() endl;
}void TestOtherFunction()
{MyString::string s1(hello world);MyString::string s2(hello bit);swap(s1, s2);s1.swap(s2);cout s1.c_str() endl;cout s2.c_str() endl;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()
{TestConstructionAndCopyConstruction();TestAssignmentOperatorOverloadingAndElementAccess();TestIteratorAndCapacity();TestResize();TestRserve();TestPushBackAndAppend();TestInsert();TestErase();Test();TestFind();TestSwapAndSubstr();TestStreamInsertionAndStreamExtraction();TestOtherFunction();return 0;
} 好啦,uu们,string的模拟实现这部分滴详细内容博主就讲到这里啦,如果uu们觉得博主讲的不错的话,请动动你们滴小手给博主点点赞,你们滴鼓励将成为博主源源不断滴动力,同时也欢迎大家来指正博主滴错误~