当前位置: 首页 > news >正文

宿迁网站建设介绍公司动态图片在线制作

宿迁网站建设介绍公司,动态图片在线制作,为爱直播视频,wordpress说说分类Ciallo#xff5e;(∠・ω )⌒☆ ~ 今天#xff0c;我将继续和大家一起学习C基础篇第五章下篇----string类的模拟实现 ~ 上篇#xff1a;★ C基础篇 ★ string类-CSDN博客 C基础篇专栏#xff1a;★ C基础篇 ★_椎名澄嵐的博客-CSDN博客 目录 一 基础结构 二 迭代器 …Ciallo(∠・ω )⌒☆ ~ 今天我将继续和大家一起学习C基础篇第五章下篇----string类的模拟实现 ~ 上篇★ C基础篇 ★ string类-CSDN博客 C基础篇专栏★ C基础篇 ★_椎名澄嵐的博客-CSDN博客 目录 一 基础结构 二 迭代器 三 各种接口 3.1 功能接口 3.2 插入相关接口 3.3 删除相关接口 3.4 查找相关接口 3.5 拷贝构造深拷贝 赋值 3.6 其他接口 一 基础结构 首先浅写一个基本的string类但会有几个问题~ // string.h namespace zmcl {class string{public:string() // 无参构造:_str(nullptr) // 问题2,_size(0),_capacity(0){}string(const char* str) // 带参构造{_size strlen(str);_capacity _size; // _capacity不包含/0_str new char[_capacity 1];strcpy(_str, str);}const char* c_str() // 获取字符串{return _str;}~string() // 析构{delete[] _str;_str nullptr;_size _capacity 0;}private:char* _str;size_t _size;size_t _capacity;};void test_string1() // 问题1{string s1;string(hello zmcl);} } // string.cpp #includestring.h //.....//test.cpp #includestring.h int main() {zmcl::test_string1();return 0; } 问题1以上程序在运行时会报一个链接错误 因为头文件会在两个.cpp文件中分别展开类中的函数会因为内联不会放入符号表中不会报错。但类外的全局函数test_string1会在两个cpp文件中各有一份导致重定义。 两个解决方法 改为static void test_string1()声明定义分离 问题2 void test_string1() {string s1;string s2(hello zmcl);cout s1.c_str() endl;cout s2.c_str() endl; } 此时程序会报错因为类中的无参构造用了初始化列表_str为空指针并没有自带 \0 而在获取字符串的时候遇到 \0 才会返回所以无参构造应该为 string():_str(new char[1] {\0}), _size(0), _capacity(0) {} 那~可不可以把有参和无参构造合并一下呢~ string(const char* str ) // 给空会自带 \0 {_size strlen(str);_capacity _size; // _capacity不包含/0_str new char[_capacity 1];strcpy(_str, str); // 先拷贝后判断\0也会拷贝 } 最后的基本结构为~~ namespace zmcl {class string{public:string(const char* str ) // 给空会自带 \0{_size strlen(str);_capacity _size; // _capacity不包含/0_str new char[_capacity 1];strcpy(_str, str); // 先拷贝后判断\0也会拷贝}const char* c_str(){return _str;}size_t size() const{return _size;}size_t capacity() const{return _capacity;}char operator[](size_t pos){assert(pos _size);return _str[pos];}const char operator[](size_t pos) const{assert(pos _size);return _str[pos];}~string(){delete[] _str;_str nullptr;_size _capacity 0;}private:char* _str;size_t _size;size_t _capacity;}; } 二 迭代器 class string { public: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;}//... } 有了迭代器就可以使用迭代器遍历和范围for遍历了~ 三 各种接口 3.1 功能接口 reserve void string::reserve(size_t n) {if (n _capacity){char* tmp new char[n 1]; //开新数组strcpy(tmp, _str); // 拷贝原数组delete[] _str; // 删除原数组_str tmp; // 指向新数组_capacity n;} } 3.2 插入相关接口 push_back 尾插字符 void string::push_back(char ch) {if (_size _capacity) // 扩容{reserve(_capacity 0 ? 4 : _capacity * 2);}_str[_size] ch;_size;_str[_size] \0; // 兼容C } 空扩4非空扩2倍~ 最后位置要加 \0 不然会出现乱码~ append 尾插字符串 void string::append(const char* str) {size_t len strlen(str);if (_size len _capacity){// 大于2倍开多少给多少 不够2倍按2倍开reserve(_size len 2 * _capacity ? _size len : 2 * _capacity);}strcpy(_str _size, str);_size len; } operator 尾插 string string::operator(char ch) {push_back(ch);return *this; }string string::operator(const char* str) {append(str);return *this; } 测试一下~ insert 指定位置插字符 void string::insert(size_t pos, char ch) {assert(pos _size);if (_size _capacity) // 扩容{reserve(_capacity 0 ? 4 : _capacity * 2);}// 挪数据size_t end _size;while (end pos)// pos~end位置的值往后移一格{_str[end 1] _str[end];--end;}_str[pos] ch; } 上程序在头插时会出大问题end作为一个无符号整数和另一个无符号整数pos比较时end 不会减到负数就算end改为int类型比较时也会隐式类型转换变为无符号整数。 两个解决方法 比较时强转 while (end (int)pos) 使end指向\0后一个位置 void string::insert(size_t pos, char ch) {assert(pos _size);if (_size _capacity) // 扩容{reserve(_capacity 0 ? 4 : _capacity * 2);}// 挪数据size_t end _size 1; // 使end指向\0后一个位置while (end pos) // pos~end-1 位置的值往后移一格{_str[end] _str[end - 1];--end;}_str[pos] ch; } insert 指定位置插字符串 void string::insert(size_t pos, const char* str) {assert(pos _size);size_t len strlen(str);if (len 0) // 0直接返回return; // 扩容if (_size len _capacity){// 大于2倍开多少给多少 不够2倍按2倍开reserve(_size len 2 * _capacity ? _size len : 2 * _capacity);}// 挪数据size_t end _size len;while (end pos len - 1){_str[end] _str[end - len];--end;}// 填数据for (size_t i 0; i len; i){_str[pos i] str[i];}_size len; } 3.3 删除相关接口 erase 删除一段 // string.h // 声明时给默认 void erase(size_t pos, size_t len npos); static const size_t npos;// string.cpp const size_t string::npos -1; // 定义时给不给默认 void string::erase(size_t pos, size_t len) {if (len _size - pos)// pos后全删{_str[pos] \0;_size pos;}else // 删了中间一段{for (size_t i pos len; i _size; i) // 往前调{_str[i - len] _str[i];}_size - len;_str[_size] \0;} } 3.4 查找相关接口 find 查找字符或字符串 // string.h 声明 size_t find(char ch, size_t pos 0); size_t find(const char* str, size_t pos 0); // string.cpp 定义 size_t string::find(char ch, size_t pos) {for (size_t i 0; i _size; i){if (_str[i] ch)return i;}return npos; } size_t string::find(const char* str, size_t pos) {assert(pos _size);const char* ptr strstr(_str pos, str);if (str nullptr)return npos;elsereturn ptr - _str; } substr 查找子串 // string.h 声明 string substr(size_t pos 0, size_t len npos); // string.cpp 定义 string string::substr(size_t pos, size_t len) {assert(pos _size);if (len _size - pos) // 取到结尾的情况{len _size - pos; // len大于剩余字符长度更新len}string sub;sub.reserve(len);for (size_t i 0; i len; i){sub _str[pos i];}return sub; } 我们小测一下这三个查找接口~ void test_string() {string s(zmcl.cpp.zip);size_t pos s.find(.);string suffix s.substr(pos);cout suffix.c_str() endl; } 报错了了了_ 此时因为没有手写拷贝构造编译器使用了浅拷贝sub出函数会销毁release版本下进行了优化suffix直接充当了sub故不会报错~ 但是程序还需要改进~加拷贝构造~ 3.5 拷贝构造深拷贝 赋值 以下程序使用了浅拷贝在debug 和 release版本下都会崩~ void test_string() {string s(zmcl.cpp.zip);string copy(s);cout copy.c_str() endl; } 手写深拷贝~ // s2(s1) s2-this s1-s string(const string s) {_str new char[s._capacity 1];strcpy(_str, s._str);_size s._size;_capacity s._capacity; } 加完以后就不会报错辣~ 当然还有更简单的写法直接创一个新的再交换给this~ void swap(string s) {std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity); } // s2(s1) s2-this s1-s string(const string s) {string tmp(s._str);swap(tmp); } 此时s为空会出现随机值需要在类里给初始值~ private:char* _str nullptr;size_t _size 0;size_t _capacity 0; 赋值 不手动写赋值也会出问题甚至会发生内存泄漏~ // s2 s1 s2-this s1-s string operator(const string s) {if (this ! s) // 防止自己给自己赋值直接返回~{delete[] _str; // 预防浪费空间直接删除原空间_str new char[s._capacity 1]; // 开辟新空间strcpy(_str, s._str);_size s._size;_capacity s._capacity;}return *this; } 赋值也可以使用现代写法~让tmp当黑奴() // s2 s1 s2-this s1-s string operator(const string s) {if (this ! s){string tmp(s);swap(tmp);}return *this; } 甚至还能再简化~ string operator(string tmp) {swap(tmp);return *this; } 3.6 其他接口 operator 比较  operator 系列写两个其他复用~  bool operator(const string s1, const string s2) {return strcmp(s1.c_str(), s2.c_str()) 0; } bool operator(const string s1, const string s2) {return !(s1 s2); } bool operator(const string s1, const string s2) {return s1 s2 || s1 s2; } bool operator(const string s1, const string s2) {return s1 s2 || s1 s2; } bool operator(const string s1, const string s2) {return strcmp(s1.c_str(), s2.c_str()) 0; } bool operator!(const string s1, const string s2) {return !(s1 s2); } io流  ostream operator(ostream out, const string s) {for (auto ch : s){out ch;}return out; } istream operator(istream in, string s) {s.clear();// 防止s中本来有数据// 防止扩容过度const int N 256;// buff是临时数组不会永久存在并且栈中开空间很快char buff[N]; int i 0;char ch;in ch;while (ch ! ch ! \n){// 先传到buff数组满了则到s并重置ibuff[i] ch;if (i 255){buff[i] \0;s buff;i 0;}// in ch; 这样写遇到空格不会停止ch in.get();}// 若buff中还有内容if (i 0){buff[i] \0;s buff;}return in; } ~完~
http://www.w-s-a.com/news/157355/

相关文章:

  • 网站开发的项目17岁高清免费观看完整版
  • 手机网站建设多少钱一个门网站源码
  • 重庆 网站开发天津住房和城乡建设厅官方网站
  • 泰安高级网站建设推广厦门高端网站建设定制
  • jsp网站开发引用文献手机seo排名
  • 创建一家网站如何创设计网页的快捷网站
  • 1688代加工官方网站h5开发教程
  • 静态网站源码下载网站怎么显示备案号
  • 网站代码设计网站开发维护任职要求
  • 长寿做网站的电话怎么快速刷排名
  • 上海市中学生典型事例网站邯郸全网推广
  • 厦门网站建设680元好男人的最好的影院
  • 石家庄网站建设设计产品设计专业就业前景
  • 网站移动排名做最好最全的命理网站
  • 网站怎么防黑客杭州市做外贸网站的公司
  • 网站推广公司认准乐云seo易语言做网站登录
  • 配色设计网站推荐网站下拉菜单重叠
  • 内容展示型网站特点在北京注册公司需要多少钱
  • h5网站源代码创意设计理念
  • 岳阳网站开发服务推广运营平台
  • 网站开发得多长时间湖南建设人力资源网证书查询
  • 论坛网站开发网络营销是什么时候产生的
  • 帮人做网站赚钱无忧软文网
  • 做网站要不要营业执照重庆网站优化seo公司
  • 学院宣传网站建设简介做网站没灵感
  • 网站建设终稿确认书网站意义学校
  • 3小时网站建设平台专业制作教学课件
  • 曲阜网站建设百度开户现货黄金什么网站可以做直播
  • 比较好的企业建站平台小程序开发外包该注意些什么
  • 建行官网官网网站吗二次元风格wordpress模板