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

网站底部模板源码洛可可设计公司估值

网站底部模板源码,洛可可设计公司估值,网站查询工具,user post wordpress目录 1. string出现的原因 1.1. C语言中的字符串处理 2. 标准库中的string类 2.1. string类 3.string类的常见构造及模拟实现 3.1. string类对象的常见构造 3.2. string类的构造函数 3.3. string的拷贝构造 3.4. string类的赋值拷贝 3.4.1. 常规构造 3.4.2. 考虑异常…

目录

1. string出现的原因

1.1. C语言中的字符串处理

2. 标准库中的string类

2.1. string类

3.string类的常见构造及模拟实现

3.1. string类对象的常见构造

3.2. string类的构造函数

3.3. string的拷贝构造

3.4. string类的赋值拷贝

3.4.1. 常规构造

3.4.2. 考虑异常安全的解法

​编辑

4. 源码


1. string出现的原因

1.1. C语言中的字符串处理

在C语言中,字符串都是以“\0”结尾的字符集合,为了操作这个字符集合,C语言提供了str系列的标准库,如:strlen、strcat、strcpy等。但是这些函数与字符串时分离的,也就是说,C语言中的字符串并不是以对象形式出现的,所以这就并不符合C++中的面向对象的思想,并且底层空间依然需要用户自己管理,而且可能出现越界访问的情况。

为了更加方便地使用字符串,C++设计了string类。


2. 标准库中的string类

2.1. string类

string官方文档

在使用string类时,一定要包含#include<string>,这里注意区分string和string.h!!!

  • 字符串使用了表示字符序列的类(string就是将一堆字符按顺序存放的类)

  • 标准字符串类提供了对此类对象的支持,其接口就类似于标准字符串容器的接口,只不过单独提供了对于单字节字符串的操作

  • string 类是使用 char 作为它的字符类型,使用它的默认 char_traits 和分配器类型(也就是string其实就是一个别名)

  • string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)

  • 这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作

总结:

  • string是表示字符串的字符串类
  • 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作
  • string在底层实际是:basic_string模板类的别名(using string = std::basic_string<char>)
  • 不能操作多字节或者变长字符的序列

3.string类的常见构造及模拟实现

3.1. string类对象的常见构造

int main()
{string s1;         //构造空的s1  等价于string s1("");string s2("hello");//用C格式字符串构造string s3(s2);     //调用拷贝构造函数 return 0;
}


3.2. string类的构造函数

接下来我们模拟实现一下string的构造函数。

class string
{
public://全缺省构造函数string(const char* str = ""): _size(strlen(str)), _capacity(_size){//实际上要多开一个 留给'\0'_str = new char[_capacity + 1];strcpy(_str, str);//会把'\0也拷过去'}
private:char* _str;size_t _size;//有效字符数量,不包括"\0"size_t _capacity;//
};

这段代码还是比较简单的,就是要注意,strcpy会将字符串末尾“\0”也拷贝过去。


3.3. string的拷贝构造

基本写法:

	string(const string& s):_size(strlen(s._str)),_capacity(_size){_str = new char[_capacity + 1];strcpy(_str, s._str);}

现代写法:

        void swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}//现代写法string(const string& s):_str(nullptr),_size(0),_capacity(0){string tmp(s._str);swap(tmp);}

这里的基本写法不能理解,但是这个现代写法似乎有点抽象,我们在后面的赋值拷贝来进行讲解。


3.4. string类的赋值拷贝

3.4.1. 常规构造

我们在写任何一个一个类型的赋值运算符重载类型的时候都要考虑下面这几个问题:

  • 是否将返回值类型设置为该类型的引用,并在函数结束时返回该实例自身的引用。因为只有返回引用,才能支持连续赋值。如果是void,那么该重载的赋值运算符将不支持连续赋值。

  • 是否将传入的参数声明为该类型的引用,因为如果传入的是实例,那么从形参到实参还需要调用拷贝构造函数,传引用就可以避免这样的无谓消耗,提升代码效率。同时我们在赋值运算符内部不会对实例产生修改,所以将在引用参数前面加上const关键字。
string& operator=(const string& s)
  • 赋值前是否将就内存清理掉了,如果没有释放掉已有的内存,可能就会导致内存泄漏。
  • 判断传入的参数与当前实例是不是同一个实例,如果是的话不进行赋值直接返回。如果现实没有做这个判断,传入参数与与当前实例是同一个实例,那么在释放就内存的时候,传入的参数的内存也被释放掉了,就会找不到要赋值的东西了。

结合上面四点我们写出下面的代码:

	string& operator=(const string& s){if (this == &s)return *this;//自己赋值自己 直接返回delete[] _str;_str = nullptr;_str = new char[strlen(s._str) + 1];strcpy(_str, s._str);return *this;}

这个代码已经能够解决我们上面提到的问题了,但是我们考虑一种更加极端的安全情况,那就是,如果在delete[ ] _str之后,系统没有足够的空间来new char[ ],那么此时就会抛出异常,那么此时_str就会处于既不是nullptr,也没有保持原来状态,这就违背了异常安全原则。

3.4.2. 考虑异常安全的解法

有两种方法来解决这个安全问题:

  • 第一种简单的方法就是,先分配新内存,然后在delete旧内存,这样的话就算分配内存没有成功,也不会破坏掉原来的string实例
  • 第二种方法就是我创建一个临时实例,这个临时实例是传入实例的副本,因为是调用的拷贝构造函数,所以抛出内存分配异常会在修改实例状态前。然后我们交换临时实例和原来实例,又因为临时实例是一个局部变量,出了函数的作用域会自动调用析构函数
	string& operator=(const string& s){if (this != &s){string tmp(s._str);std::swap(_str, tmp._str);std::swap(_size, tmp._size);std::swap(_capacity, tmp._capacity);}return *this;}

然后我们来看看我们模拟string的效果:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
namespace s
{class string{public://全缺省的构造函数string(const char* str = ""):_size(strlen(str)), _capacity(_size){//实际上要多开一个 留给'\0'_str = new char[_capacity + 1];strcpy(_str, str);//会把'\0也拷过去'}string(const string& s):_size(strlen(s._str)), _capacity(_size){_str = new char[_capacity + 1];strcpy(_str, s._str);}//string& operator=(const string& s)//{//	if (this == &s)//		return *this;//自己赋值自己 直接返回//	delete[] _str;//	_str = nullptr;//	_str = new char[strlen(s._str) + 1];//	strcpy(_str, s._str);//	return *this;//}string& operator=(const string& s){if (this != &s){string tmp(s._str);std::swap(_str, tmp._str);std::swap(_size, tmp._size);std::swap(_capacity, tmp._capacity);}return *this;}~string(){if (_str){delete[] _str;_str = nullptr;_size = 0;_capacity = 0;}}private:char* _str;size_t _size;//有效字符个数 不算'/0';size_t _capacity;//实际存储有效字符的空间};
}int main()
{s::string s1("Hello World");s::string s2;s::string s3;/*std::string s1("Hello World");std::string s2;std::string s3;*/s3 = s2 = s1;return 0;
}

赋值前:

赋值后:


4. 源码

string模拟代码


(本篇完)

http://www.dtcms.com/a/534746.html

相关文章:

  • h5网站建设方案.doc湖南营销型网站建设价格
  • 大学国际化网站建设个人网站设计模板中文
  • 网站大全软件下载工程施工合同协议书范本
  • 什么样的网站开发比较吃香中国建筑集团有限公司官网测评网址
  • 广州网站开发定制需要多少钱永川网站设计
  • 微擎微网站开发网络科技公司网站源码
  • 谷歌网站站长指南网站设计的要求有哪些
  • 渭南网站制作学校播州区建设局网站
  • 如何与对方网站做相互链接做优化网站注意什么
  • 展示型网站建设流程网页怎么绑定wordpress
  • 辽宁住房建设部网站怎么让wordpress
  • 奉贤做网站制作1688域名网站
  • 免费奖励代码网站新闻静态网站咋做
  • 网站建设营销外包公司排名中国交通建设监理协会网站打不开
  • 免费手机建站平台wordpress调用page
  • 网站开发概要设计二建报名时间2023年报名时间
  • ps做图游戏下载网站有哪些内容网页设计改版
  • 定制家具网站平台网站开发就业培训班
  • 网站建设的网站分析怎么写做直播网站赚钱吗
  • 有什么网站可以做婚庆视频素材靖安县城乡规划建设局网站
  • 外国做爰网站wordpress多站批量发布
  • 网站调用字体电商运营数据分析表格
  • 做一个招聘信息的网站_用什么做网站的软件公司电子商务网站建设规划方案
  • 网站建设的意义以及重要性宋朝网站应该怎么做
  • 注册网站需要房产证多用户商城源码下载
  • 昆明专业网站建设的公司网络平台运营计划方案
  • 男女做爰高清免费网站免费3d建模软件
  • 佛山网站建设机构wordpress 满屏主题
  • 沙坪坝网站开发WordPress简单百度站长插件
  • 便宜建站vps永安市建设局网站