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

铜仁网站建设哪家专业南京高端定制网站建设

铜仁网站建设哪家专业,南京高端定制网站建设,查降权网站,个人网站源码php#x1f493;博主CSDN主页:Am心若依旧#x1f493; ⏩专栏分类c从入门到精通⏪ #x1f69a;代码仓库:青酒余成#x1f69a; #x1f339;关注我#x1faf5;带你学习更多c   #x1f51d;#x1f51d; 1.前言 本章重点 本章主要介绍一些关键接口的模拟实现#xff… 博主CSDN主页:Am心若依旧 ⏩专栏分类c从入门到精通⏪ 代码仓库:青酒余成 关注我带你学习更多c   1.前言 本章重点 本章主要介绍一些关键接口的模拟实现例如:构造函数拷贝构造函数析构函数赋值重载函数插入删除函数等等。 2.默认成员函数 在实现默认成员函数之前先确定成员变量 namespace wzz {class string{private:char* _str;//用一个字符数组来模拟stringsize_t _size;//数组中实际有效的个数size_t _capacity;//数组中容量的大小static const size_t npos;//静态成员变量来表示最大值};const string::size_t npos-1;//静态成员变量在类内声明在类外定义 }1.默认构造函数--当没有传值的时候就用一个缺省值来代替--这个缺省值用空字符串代替 string (const char* str) {_strnew char[_capacity1];_sizestrlen(str);_capacity_size;//初始时容量就让其等于有效元素的个数strcpy(_str,str); } 补充迭代器构造 template class Inputeiterrator string(Inputeiterator begin,Inputeriterator end) {while(begin!end){push_back(*begin);begin; } } 2.拷贝构造函数--用一个char*来初始化另一个char* 在这里会详细介绍深浅拷贝--后续就不在重点介绍了 浅拷贝拷贝出来的目标对象的指针和源对象的指针指向的内存空间是同一块空间。其中一个对象的改动会对另一个对象造成影响。 深拷贝深拷贝是指源对象与拷贝对象互相独立。其中任何一个对象的改动不会对另外一个对象造成影响。 很明显深拷贝比浅拷贝更加安全不会有同一块空间析构两次的问题。 这里拷贝构造就介绍两种写法 法一开辟一块空间然后把数据拷贝过来--如下图 代码 string (const string s):_size(s._size):_capacity(s._capacity):_str(new char[_capacity1]) {strcpy(_str,s._str); } 法二利用swap函数 法二与法一的思想不同先根据源字符串的C字符串调用构造函数构造一个tmp对象然后再将tmp对象与拷贝对象的数据交换即可。拷贝对象的_str与源对象的_str指向的也不是同一块空间是互相独立的。 代码如下 string(const string s):_str(nullptr), _size(0), _capacity(0) {string tmp(s.begin(),s.end()); //调用构造函数(这里用的是迭代器构造)构造出一个C字符串为s._str的对象swap(tmp); //交换这两个对象 }swap函数的模拟实现 只需要把每个成员变量进行交换即可 //交换两个对象的数据 void swap(string s) {//调用库里的swapstd::swap(_str, s._str); //交换两个对象的C字符串std::swap(_size, s._size); //交换两个对象的大小std::swap(_capacity, s._capacity); //交换两个对象的容量 }这里推荐使用方法二来模拟实现构造函数 3.赋值重载函数 这里也涉及到深浅拷贝的问题--因此提供两种深拷贝的写法 法一把原来的空间直接释放然后开辟新空间然后再赋值 //法一 string operator(const string s) {if (this ! s) //防止自己给自己赋值{delete[] _str; //将原来_str指向的空间释放_str new char[s._capacity 1]; //重新申请一块空间strcpy(_str, s._str); //将s._str拷贝一份到_str_size s._size; //_size赋值_capacity s._capacity; //_capacity赋值}return *this; //返回左值支持连续赋值 }法二用交换函数 //方法二 string operator(const string s) {if (this ! s) //防止自己给自己赋值{string tmp(s); //用s拷贝构造出对象tmpswap(tmp); //交换这两个对象}return *this; //返回左值支持连续赋值 }注意 用传值返回还是传引用返回要看你返回的这个值除了作用域还在不在如果在的话就可以使用传值返回如果不在的话就一定要使用传引用返回否则就会报错。 4.析构函数 string类的析构函数需要我们进行编写因为每个string对象中的成员_str都指向堆区的一块空间当对象销毁时堆区对应的空间并不会自动销毁为了避免内存泄漏我们需要使用delete手动释放堆区的空间。 //析构函数 ~string() {delete[] _str; //释放_str指向的空间_str nullptr; //及时置空防止非法访问_size 0; //大小置0_capacity 0; //容量置0 }3.迭代器相关函数 string类中的迭代器实际上就是字符指针只是给字符指针起了一个别名叫iterator而已。 typedef char* iterator; typedef const char* const_iterator;   注意不是所有的迭代器都是指针比如在list中迭代器就是节点 begin函数---返回字符的第一个地址 iterator begin() {return _str; //返回字符串中第一个字符的地址 } const_iterator begin()const {return _str; //返回字符串中第一个字符的const地址 }end函数---返回字符的最后一个地址即\0的地址 iterator end() {return _str _size; //返回字符串中最后一个字符的后一个字符的地址 } const_iterator end()const {return _str _size; //返回字符串中最后一个字符的后一个字符的const地址 }4.容量大小相关的函数 size和capacity 因为string类的成员变量是私有的我们并不能直接对其进行访问所以string类设置了size和capacity这两个成员函数用于获取string对象的大小和容量 size函数用于获取字符串当前的有效长度不包括’\0’。 //大小 size_t size()const {return _size; //返回字符串当前的有效长度 }capacity用于获取当前的容量 //容量 size_t capacity()const {return _capacity; //返回字符串当前的容量 }reverse和resize reverse--只有当大于当前容量时才会进行扩容其他不关心 //改变容量大小不变 void reserve(size_t n) {if (n _capacity) //当n大于对象当前容量时才需执行操作{char* tmp new char[n 1]; //多开一个空间用于存放\0strncpy(tmp, _str, _size 1); //将对象原本的C字符串拷贝过来包括\0delete[] _str; //释放对象原本的空间_str tmp; //将新开辟的空间交给_str_capacity n; //容量跟着改变} }注意代码中使用strncpy进行拷贝对象C字符串而不是strcpy是为了防止对象的C字符串中含有有效字符’\0’而无法拷贝strcpy拷贝到第一个’\0’就结束拷贝了。 reseize 1、当n大于当前的size时将size扩大到n扩大的字符为ch若ch未给出则默认为’\0’。  2、当n小于当前的size时将size缩小到n。 //改变大小 void resize(size_t n, char ch \0) {if (n _size) //n小于当前size{_size n; //将size调整为n_str[_size] \0; //在size个字符后放上\0}else //n大于当前的size{if (n _capacity) //判断是否需要扩容{reserve(n); //扩容}for (size_t i _size; i n; i) //将size扩大到n扩大的字符为ch{_str[i] ch;}_size n; //size更新_str[_size] \0; //字符串后面放上\0这里如果不放\0后续就会产生错误} }empty--判断是否还有元素 //判空 bool empty() {return _size 0; }5.与插入删除有关的函数 insert函数的作用是在字符串的任意位置插入字符或是字符串。 insert函数用于插入字符时首先需要判断pos的合法性若不合法则无法进行操作紧接着还需判断当前对象能否容纳插入字符后的字符串若不能则还需调用reserve函数进行扩容。插入字符的过程也是比较简单的先将pos位置及其后面的字符统一向后挪动一位给待插入的字符留出位置然后将字符插入字符串即可。 //在pos位置插入字符 string insert(size_t pos, char ch) {assert(pos _size); //检测下标的合法性if (_size _capacity) //判断是否需要增容{reserve(_capacity 0 ? 4 : _capacity * 2); //将容量扩大为原来的两倍}char* end _str _size;//将pos位置及其之后的字符向后挪动一位while (end _str pos){*(end 1) *(end);end--;}_str[pos] ch; //pos位置放上指定字符_size; //size更新return *this; }如果要用于插入字符串也是和上述插入一个字符同理 //在pos位置插入字符串 string insert(size_t pos, const char* str) {assert(pos _size); //检测下标的合法性size_t len strlen(str); //计算需要插入的字符串的长度不含\0if (len _size _capacity) //判断是否需要增容{reserve(len _size); //增容}char* end _str _size;//将pos位置及其之后的字符向后挪动len位while (end _str pos){*(end len) *(end);end--;}memcpy(_str pos, str, len); //pos位置开始放上指定字符串_size len; //size更新return *this; }push_back和push_front void push_back(char ch) {insert(_size(),ch); }void push_front(char ch) {insert(0,ch); }erase函数 erase函数的作用是删除字符串任意位置开始的n个字符。删除字符前也需要判断pos的合法性进行删除操作的时候分两种情况 1、pos位置及其之后的有效字符都需要被删除。 这时我们只需在pos位置放上’\0’然后将对象的size更新即可。 2.删除pos位置的一部分len长度的字符 //删除pos位置开始的len个字符 string erase(size_t pos, size_t len npos) {assert(pos _size); //检测下标的合法性--下标是0-_size-1,所以删除的位置不能超过_sizesize_t n _size - pos; //pos位置及其后面的有效字符总数if (len n) //说明pos位置及其后面的字符都被删除{_size pos; //size更新_str[_size] \0; //字符串后面放上\0}else //说明pos位置及其后方的有效字符需要保留一部分{strcpy(_str pos, _str pos len); //用需要保留的有效字符覆盖需要删除的有效字符_size - len; //size更新}return *this; }pop_back和pop_front函数 void pop_back() {erase(_size,1); }void pop_front() {erase(0,1); } append函数 主要含义就是在尾部追加字符串 //尾插字符串 void append(const char* str) {insert(_size, str); //在字符串末尾插入字符串str }6.访问相关函数 operator[]---实际是一个函数重载 //[]运算符重载可读可写---由于是char*的结构支持下标随机访问 char operator[](size_t i) {assert(i _size); //检测下标的合法性return _str[i]; //返回对应字符 }//只能读 const char operator[](size_t i) {assert(i _size); //检测下标的合法性return _str[i]; //返回对应字符 }find函数 找到了就返回下标没找到就返回npos即-1 //正向查找第一个匹配的字符 size_t find(char ch, size_t pos 0) {assert(pos _size); //检测下标的合法性for (size_t i pos; i _size; i) //从pos位置开始向后寻找目标字符{if (_str[i] ch){return i; //找到目标字符返回其下标}}return npos; //没有找到目标字符返回npos }7.总结 string类的大部分重要接口都已经完全的实现了,希望这部分内容能够重点掌握--因为在面试的过程中很有可能考官让你手撕一个string类 下期预告vector
http://www.w-s-a.com/news/586161/

相关文章:

  • 企业信息管理系统免费seo优化个人博客
  • 做任务的设计网站泰州哪里做网站
  • 什么网站可以做设计赚钱吗南京十大软件公司排名
  • 网站开发时间进度北京有哪些著名网站
  • 深圳比较好的设计网站公司自己的网站到期域名如何续费
  • 温州做网站哪儿新云网站模版
  • 网站开发 视频存在哪检察院前期网站建设
  • 备案中的网站信息怎么填如何做分享赚钱的网站
  • 网站行程表怎么做注册公司费用要多少
  • 常见电子商务网站基本模式南山网站公司定
  • 网站搭建代码网站里面送礼物要钱怎么做代码
  • 大学英文网站建设举措wordpress 学院 模板
  • 爱 做 网站吗php网站作业模版
  • wordpress代码乱吗台州做网站seo的
  • 做ptt网站wordpress中文企业网站
  • 深圳雨棚制作深圳 网站优化公司排名
  • 深圳优秀网站建设价格wordpress没人用
  • 国企网站建设需要注意沈阳招标信息网
  • 东莞360推广的网站是谁做的上海网络推广产品
  • 网站可以换主机吗中国十大网站建设企业
  • 怎么做盗版小说网站官网做有下拉列表的网站的图片
  • 邢台网站建设电话网站界面类型
  • 网站制作合同模板做一个网站能挣多少钱
  • 汶上1500元网站建设互联网高端官网
  • 广州做公司网站网站开发培训机构
  • 网站建设与维护 课件网页版qq安全中心登录入口
  • 做三个月网站广告收入dw如何制作网页
  • ...课程网站建设简介工信部 网站备案查询
  • 网站代码建设 实例企业网站建设大概的费用
  • 制作网站软件排行榜过年做啥网站致富