网站备案升级如何做网站后台管理
网站备案升级,如何做网站后台管理,北京知名的网站建设公司排名,北京动力 网站建设本章主要说一下模拟实现string类的部分功能#xff0c;文章末附上所有代码。
目录
一、构造函数与析构函数
二、拷贝构造
三、c_str
四、【】和迭代器的遍历与访问
五、size
六、判断
七、reserve
八、push_back
九、resize
十、append
十一、
十二、insert
十…本章主要说一下模拟实现string类的部分功能文章末附上所有代码。
目录
一、构造函数与析构函数
二、拷贝构造
三、c_str
四、【】和迭代器的遍历与访问
五、size
六、判断
七、reserve
八、push_back
九、resize
十、append
十一、
十二、insert
十三、erase
十四、全部代码 一、构造函数与析构函数
首先构造函数就是利用之前所学的知识进行构造利用初始化列表进行计算一下所需要初始化的对象的大小也就是字符串的大小如下方代码所示size显示利用strlen计算一下所需要的大小然后容量这里是利用了三目运算符判断一下如果字符串为空就多创建几个如果字符串有大小就创建字符串大小的容量然后利用new进行创建这里需要把‘\0’算上所以就是容量1然后在利用strcpy拷贝过去析构函数就是利用delete[ ] 去释放所申请的空间并且置为空再把size和capacity置为0这个就是析构函数的写法那么实践一下是否成功测试结果如下图可以从图一看到构造函数很成功图二也可以看出析构函数也很成功。 class String { public: String(const char* str ) :_size(strlen(str)) { _capacity _size 0 ? 4 : _size; _str new char[_capacity 1]; strcpy(_str, str); } ~String() { if (_str) { delete[] _str; _str nullptr; _size _capacity 0; } } private: char* _str; size_t_size; size_t_capacity; }; void Test1() { String s1; String s2(Hello word!); } int main() { Test1(); return 0; } 那么如果利用s2这个已有的字符串创建呢可以吗
如下图一可以看出在第一次析构函数调用成功后s3是正常析构可是s2的字符串就变成了乱码也就是这块地址被释放了如图二s2和s3所指向了同一个地址这个就是之前讲过的构成了拷贝构造所以编译器自动生成了一个拷贝构造但是这个只是一个值拷贝也就是浅拷贝所以就会出现指同一个空间的情况所以这里的解决方法就是如下方代码所是这样利用引用进行构造这个对象可以从下方图三看出地址不是一样这样就不会出现图一图二的错误了。 String(const String s) :_size (s._size) ,_capacity(s._capacity) { _str new char[_capacity 1]; strcpy(_str, s._str); } 二、拷贝构造
在赋值的时候编译器所自动生成的拷贝就是浅拷贝所以这里需要自己写一个深拷贝要不然用s2给s1赋值都赋值不了实现代码如下测试如图发现是可以进行赋值的这里是先判断这两个地址是否相同不同的话进行拷贝首先是创建了一个行的地址里面存放的就是需要拷贝的字符串然后再把旧的字符串释放掉在指向这个地址size和capapcity都赋值成等于号的右值。 String operator(const String s) { if (this ! s) { char* tmp new char[s._capacity 1]; strcpy(tmp, s._str); delete[] _str; _str tmp; _size s._size; _capacity s._capacity; } return *this; } 三、c_str
这个在官方的文档中的意思就是返回c形式的字符串因为使用流插入的话遇到\0并不会停止会全部打印结束所以这里就是需要这种函数来应付这种场合测试图和代码如下这里不需要改动字符串只是访问所以利用const修饰了一下下文这中只读的都会利用const去修饰。 const char* c_str() { return _str; } 四、【】和迭代器的遍历与访问
这个就是相当于运算符重载利用【】去访问与遍历像数组那样访问与遍历上篇文章说了有三种访问与遍历的方式【】访问迭代器遍历和范围for的遍历[]的测试结果和代码如下。 const char operator[](size_t pos) const { assert(pos _size); return _str[pos]; } 迭代器这里就下了两种的一种是可读可写的另一种就是只读的也就是const_iterator这种类型的普通的测试代码和结果如下。 iterator begin() { return _str; } iterator end() { return _str _size; } String::iterator it s2.begin(); while (it ! s2.end()) { cout *it; it; *it a; } cout endl; 如果把s3转成const类型进行利用迭代器就会不能给改错误如下这时就可以利用const_iterator这个了实现代码如下。 const_iterator begin() const { return _str; } const_iterator end() const { return _str _size; } for这个语法糖可以直接访问因为这个底层就是迭代器代码如下。 for (auto it3 : s2) { cout it3; } cout endl; 五、size
这个就是获取对象的size数据也就是大小代码和测试结果如下这里就可以利用之前获取的size数据直接返回。 size_t size() const { return _size; } 六、判断
这个就是说下几个判断判断的是字符串的ASCLL码值直接利用strcmp进行直接复用判断使用代码和测试结果如下。 bool operator(const String s) const { return strcmp(_str, s._str) 0; } bool operator(const String s) const { return strcmp(_str, s._str) 0; } bool operator(const String s) const { return *this s || s *this; } bool operator(const String s) const { return !(*this s); } bool operator(const String s) const { return !(*this s); } bool operator!(const String s) const { return !(*this s); } 七、reserve
这个函数的用法就是创建一个空间这个空间的大小可以进行指定也就是相当于扩容代码与测试结果如下s1也成功扩容成功他先是创建一个足够大的地址空间然后释放掉旧的在把临时拷贝的地址给原来的指针就OK了。 void reserve(size_t n) { char* tmp new char[n 1]; strcpy(tmp, _str); delete[] _str; _str tmp; _capacity n; } 八、push_back
这个我看到的时间就想起了之前学习数据结构的时候尾插这个尾插写的时候就是判断当size1大于capacity的时候就进行扩容我这里是扩容的2倍然后在进行拷贝数据在把size然后在把字符串尾写上\0如下图可以看出尾插是正常的代码如下。 void push_back(char ch) { if (_size 1 _capacity) { reserve(_capacity * 2); } _str[_size] ch; _size; _str[_size] \0; } 九、resize
这个在cplusplus网站中的解释如下图可以看出他有两个参数第一个是长度第二个是字符就是进行扩容然后如果新的地址比旧的长的时候就把后面的字符尾插在字符后面实现代码如下下方图二就是测试的结果。 void resize(size_t n,char c) { char* tmp new char[n 1]; strcpy(tmp, _str); while (n-_size-1) { tmp[_size] c; _size; } delete[] _str; _str tmp; _capacity n; _size; _str[_size] \0; } 十、append
这个就是和push_back的用法差不多但是是追加字符串这个用法就是直接计算字符串长度然后开辟空间在把字符串拷贝过去如下图所示。 void append(const char* str) { size_t len strlen(str); if (_size len _capacity) { reserve(_size len); } strcpy(_str _size, str); _size len; } 十一、
这里是直接复用了push_back和append代码和测试如下。 String operator(char ch) { push_back(ch); return *this; } String operator(const char* str) { append(str); return *this; } 十二、insert
这个insert就是在pos位置插入字符如下方代码就可以看出有_size可以找出字符串的尾然后--挪动数据找到pos的位置然后插入字符再把size对了不能忘了先判断扩容测试代码如下。 void insert(size_t pos, char ch) { assert(pos _size); if (_size 1 _capacity) { reserve(2 * _capacity); } size_t end _size; while (end pos) { _str[end 1] _str[end]; --end; } _str[pos] ch; _size; } 十三、erase
把pos位置数据删除这里也就是直接找到pos位置然后直接覆盖在--size就可以了测试代码和结果如下。 void erase(size_t pos) { assert(pos _size); size_t end _size; while (end pos) { --end; } while (end _size 1) { _str[end ] _str[end1]; end; } _size--; } 十四、全部代码
#define _CRT_SECURE_NO_WARNINGS 1
#include iostream
#include string
#include assert.h
using namespace std;class String
{
public:typedef char* iterator;typedef const char* const_iterator;String(const char* str ):_size(strlen(str)){_capacity _size 0 ? 4 : _size;_str new char[_capacity 1];strcpy(_str, str);}String(const String s):_size (s._size),_capacity(s._capacity){_str new char[_capacity 1];strcpy(_str, s._str);}String operator(const String s){if (this ! s){char* tmp new char[s._capacity 1];strcpy(tmp, s._str);delete[] _str;_str tmp;_size s._size;_capacity s._capacity;}return *this;}~String(){if (_str){delete[] _str;_str nullptr;_size _capacity 0;}}const char* c_str(){return _str;}const char operator[](size_t pos) const{assert(pos _size);return _str[pos];}iterator begin(){return _str;}iterator end(){return _str _size;}const_iterator begin() const{return _str;}const_iterator end() const {return _str _size;}size_t size() const{return _size;}bool operator(const String s) const{return strcmp(_str, s._str) 0;}bool operator(const String s) const{return strcmp(_str, s._str) 0;}bool operator(const String s) const{return *this s || s *this;}bool operator(const String s) const{return !(*this s);}bool operator(const String s) const{return !(*this s);}bool operator!(const String s) const{return !(*this s);}void reserve(size_t n){char* tmp new char[n 1];strcpy(tmp, _str);delete[] _str;_str tmp;_capacity n;}void resize(size_t n,char c){char* tmp new char[n 1];strcpy(tmp, _str);while (n-_size-1){tmp[_size] c;_size;}delete[] _str;_str tmp;_capacity n;_size;_str[_size] \0;}void push_back(char ch){if (_size 1 _capacity){reserve(_capacity * 2);}_str[_size] ch;_size;_str[_size] \0;}void append(const char* str){size_t len strlen(str);if (_size len _capacity){reserve(_size len);}strcpy(_str _size, str);_size len;}String operator(char ch){push_back(ch);return *this;}String operator(const char* str){append(str);return *this;}void insert(size_t pos, char ch){assert(pos _size);if (_size 1 _capacity){reserve(2 * _capacity);}size_t end _size;while (end pos){_str[end 1] _str[end];--end;}_str[pos] ch;_size;}void erase(size_t pos){assert(pos _size);size_t end _size;while (end pos){--end;}while (end _size 1){_str[end ] _str[end1];end;}_size--;}
private:char* _str;size_t _size;size_t _capacity;
};void Test1()
{String s1;String s2(Hello word!);String const s3(s2);s1 s2;cout s2.c_str() endl;cout s2[4] endl;String::iterator it s2.begin();while (it ! s2.end()){*it a;cout *it;it;}cout endl;String::const_iterator it2 s3.begin();while (it2 ! s3.end()){cout *it2;it2;}cout endl;for (auto it3 : s2){cout it3;}cout endl;cout s2.size() 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;s1.reserve(30);s1.push_back(a);cout s1.c_str() endl;s1.resize(40, c);cout s1.c_str() endl;s2.append(dddd);cout s2.c_str() endl;s2 bbbbbbb;s2 c;cout s2.c_str() endl;s2.insert(2, q);cout s2.c_str() endl;s2.erase(2);cout s2.c_str() endl;
}int main()
{Test1();return 0;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/87730.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!