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

htm网站制作百度学术论文查重免费检测

htm网站制作,百度学术论文查重免费检测,网站开发花费,北京建工招标平台前引:上一篇文章小编已经整理出了String的常用接口,梳理了各个接口的功能、参数,如何使用等各种实例。本篇文章将带大家看看String这些接口的实践使用,探索这些接口的实用性,是如何增加代码效率的。在本篇文章的末尾&a…

 

前引:上一篇文章小编已经整理出了String的常用接口,梳理了各个接口的功能、参数,如何使用等各种实例。本篇文章将带大家看看String这些接口的实践使用,探索这些接口的实用性,是如何增加代码效率的。在本篇文章的末尾,还奉上了部分底层的模拟实现,String类的使用是有趣的,下面我们来从实践中感受String类带给我们的快捷、效率!

目录

string类的模拟实现

构造初始化

析构函数

流提取

流插入

大小比较

拷贝构造

赋值运算符重载


string类的模拟实现

下面我们来实现String的底层,解读String的原理:

std库里面的String有它的专属空间,也就是C++库

下面我们来命名自己的空间,同时String是一个类,我们需要实现:自定义空间+一个类

namespace Space
{class string{};
}
构造初始化

观察库里面的 string 初始化特点:

可以看到它的变量有三个:size、capacity、字符空间

下面我们来自己实现它的构造初始化:

初始化size、capacity、空间、存储

//自定义构造
string(const char* allocator):_size(strlen(allocator)),_capacity(2*_size+1)
{try{_allocator = new char[_capacity];}catch (const exception& _allocator){cout << "空间开辟失败" << endl;}//存储strcpy(_allocator, allocator);
}

效果展示:

 可以看到是没有问题的,但是我们平常是可能按下面的方式初始化的:

string S;

所以我们还得再写一个无参默认构造,如下:

注意:不能是全缺省的,否则参数相同,编译器无法区分

//默认构造
string():_size(0), _capacity(10)
{try{_allocator = new char[_capacity];}catch (const exception& _allocator){cout << "空间开辟失败" << endl;}
}

以上我们的构造初始化就写好了,可以随时应对各种初始化情况,总代码如下:

namespace Space
{class string{public://默认构造string():_size(0), _capacity(10){try{_allocator = new char[_capacity];}catch (const exception& _allocator){cout << "空间开辟失败" << endl;}}//自定义构造string(const char* allocator):_size(strlen(allocator)),_capacity(2*_size+1){try{_allocator = new char[_capacity];}catch (const exception& _allocator){cout << "空间开辟失败" << endl;}//存储strcpy(_allocator, allocator);}private:size_t _size;size_t _capacity;char* _allocator;};
}
析构函数

这个函数很简单,释放空间,改变 size、capacity这些就可以了,如下:

//析构
~string()
{delete[]_allocator;_size = 0;_capacity = 0;cout << "释放成功" << endl;
}
流提取

在上面我们已经实现了读取函数,但是追求方便,且两者有很大区别,比如: 

cout << S1.Read() << endl;
cout << S1 << endl;

ostream& operator<<(ostream& out, const string& _stl) //没有找命名空间里面
{for (auto ac : _stl){cout << ac;}return out;
}

注意:不能在成员函数中实现,因为this指针会抢占第一个操作符位置,所以我们放在外面实现

区别:

C的字符数组,以\0为终止算长度

String不看\0,以size为终止长度,例如:

这样看虽然没有什么区别,但是如果添加上\0就有很大的变化了

可以看到流提取是不受\0影响的,所以我们需要注意这个点,字符的打印在流提取不受\0影响 

为什么流提取的实现需要以ostream&作为返回值

(1)允许多次连续提取

(2)避免流对象的开销,规定直接传引用

strcpy与memcpy的区别

特性strcpymemcpy
参数类型char*void*
终止条件遇到\0停止按指定字节数完成复制
长度控制自动计算显式指定
数据安全高风险可控风险
适用场景纯字符串操作任意内存数据复制

所以对于字符串我们需要根据形式区分二者的拷贝,否则会出很大的问题  

流插入

在模拟流插入时我们同样要注意this指针的问题,因此需要在成员函数外面定义

我们看下面的问题:

注意(1):所以我们需要在输入之前清理之前原本的字符,然后重置_size,效果如下: 

 注意(2):我们每次调用+=,都会开辟空间,效率可以优化,先存进数组里面,再最后统一拷                         贝 

istream& operator>>(istream& in, string& _stl)
{//清理缓冲区_stl.clear();//输入元素char c = in.get();//临时数组int i = 0;char buff[128] = "\0";//直到c结束while (c != '\n' && c != '\0'){//先存入buff数组buff[i++] = c;//如果临时数组满了,就给_stlif (i == 127){memcpy(_stl._allocator, buff, i);//重置数组i = 0;}//_stl += c;//注意get会自动向后移动c = in.get();}//如果i没有重置,说明没有发生存满if (i != 127){for (int j = 0; j < i; j++){//如果满了就扩容if (_stl._size == _stl._capacity){_stl.reserve(2 * _stl._size);_stl._capacity = 2 * _stl._size;}//转移到对象里面_stl._allocator[_stl._size++] = buff[j];}}return in;
}

效果展示:

大小比较

我们拿 > 举例:大小比较我们一般采用的是运算符重载,里面根据当前字符的ASCII值比较

//大小比较
bool operator>(const string& S)const
{size_t p1 = 0, p2 = 0;//比较不同长度while (p1<_size && p2<S._size){if (_allocator[p1] == S._allocator[p2]){p1++;p2++;}else{if (_allocator[p1] > S._allocator[p2]){return true;}elsereturn false;}}//此时前面的字符都相等,但是没有比较完if (p1 < _size){return true;}elsereturn false;return false;
}

效果展示:

拷贝构造

原理我就不说了,咱们直接实现:

//拷贝构造
string(const string& S)
{_allocator = new char[S._capacity];_size = S._size;_capacity = S._capacity;//数据拷贝memcpy(_allocator, S._allocator, S._capacity);
}
赋值运算符重载

将一个对象的内容赋给另一个对象,因为前面我们已经有了一定的了解,我们下面换一种玩法:

注意:如果没有写拷贝构造等,属于浅拷贝,那么多次释放同一个空间会出问题

我们知道swap可以交换任意形式的变量,所以我们先来实现一个可以交换对象的swap:

思路:先根据赋值对象A拷贝构造一个临时对象B,然后把临时对象B的数据给*this

void swap(const string& S)
{//先开辟空间,注意S出了swap函数会销毁string tmp(S);//目的:创建一个临时变量,把临时变量的空间、大小等信息转给Sstd:: swap(_allocator, tmp._allocator);std:: swap(_size, tmp._size);std:: swap(_capacity, tmp._capacity);
}

下面我们直接调用这个swap函数就OK了:

string& operator=(string& S)
{(*this).swap(S);return *this;
}

效果展示:

最后我们再梳理以下思路:

现在有两个对象:A和B,我们的目标是A=B

进入swap函数先以B为模板调用拷贝构造出C,此时C是临时对象,内容与B完全一致

然后将C的内容交换给A,C虽然会释放,但是它在堆上开的内容只会main函数调用析构才会释放

 

这里我们先完成构造、析构,由于排版问题,下一篇我们来完成它的功能结尾!

                                                【雾非雾】期待与你的下次相遇! 

http://www.dtcms.com/wzjs/253494.html

相关文章:

  • 软件做网站注册域名在哪里注册
  • 好玩的网站源码重庆最新数据消息
  • 用wordpress和avada做网站汕头百度关键词推广
  • wordpress建站比较竞价托管 微竞价
  • 建邺做网站价格关键词爱站网关键词挖掘工具
  • 室内设计师上网第一站广告公司推广
  • 如何做英文网站外链广告网站策划方案
  • 网站建设少用控件网站客服
  • 迪士尼网站是谁做的seo点石论坛
  • seo短视频网页入口引流网站推荐直链平台
  • 佳木斯做网站百度风云榜热搜
  • 免费的logo设计网站抓取关键词的软件
  • 企业网站怎么做sem推广是什么意思呢
  • wordpress如何重置后台密码合肥网站优化公司
  • 建设一个展示商品的网站中国万网域名注册
  • div+css网页设计代码网站seo标题优化技巧
  • 使用java做新闻网站思路手机制作网页用什么软件
  • 泸州网站开发公司深圳今日头条新闻
  • 博客系统wordpress百度seo怎么查排名
  • 政府网站建设整改工作情况报告电商平台排行榜
  • 网站建设运营方案网络营销与直播电商是干什么的
  • 搜狐员工做网站的工资多少钱搜索引擎广告案例
  • 医药做网站专业黑帽seo推广
  • 免费的视频网站推广软件竞价推广的基本流程
  • 做网站是什么时候分页seo编辑的工作内容
  • 做任务网站有哪些内容常州百度关键词优化
  • 用.net做视频网站的案例上海职业技能培训机构
  • 怎么做wp网站桂林市天气预报
  • 怎么做淘宝客网站和APP郑州网络营销公司
  • 运动鞋子网站建设规划书西安网站推广助理