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

网站底部悬浮一个网站怎么绑定很多个域名

网站底部悬浮,一个网站怎么绑定很多个域名,企业还有人做网站么,网站升级建设费用吗目录 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/427581.html

相关文章:

  • 极简全营养三食材组合:土豆 + 鸡蛋 + 绿叶菜
  • Java【代码 24】AOI数据获取(通过地址名称获取UID在获取AOI数据)
  • 提升 HarmonyOS 开发效率:DevEco Studio 6.0 热更新调试模式全指南
  • 桌面预测类开发,桌面%性别,姓名预测%系统开发,基于python,scikit-learn机器学习算法(sklearn)实现,分类算法,CSV无数据库
  • 用自己服务器做网站2023营业执照年检
  • QCustomPlot 高级扩展与实战案例
  • C语言形式参数和实际参数的区别(附带示例)
  • 医疗领域的数智化转型与智能化变革研究报告:技术驱动、模式创新与政策协同
  • 在 C# 中,如何使 $““ 字符串支持换行
  • 2025年精选单北斗GNSS水库形变监测系统对比推荐
  • Java 在Word 文档中添加批注:高效文档协作的利器
  • 代做效果图网站项目管理软件的作用
  • 广东省高水平建设专业网站北京大兴网站建设
  • 使用 HBuilderX 将网页打包为安卓 APP详细步骤
  • MinerU2.5:一种用于高效高分辨率文档解析的解耦视觉-语言模型
  • Redis三大命令分类详解
  • 饼状图修复总结
  • npm 最新镜像,命令导致下载错误
  • 济宁做公司网站中职电子商务专业就业方向
  • JVM深入研究--JHSDB (jvm 分析工具)
  • AI的局限性,有所能与有所不能
  • 广州网站设计公司推荐哪家网站的风格设计有哪些
  • 【完整源码+数据集+部署教程】武装人员图像分割系统: yolov8-seg-GFPN
  • 开发避坑指南(61):Redis持久化失败:RDB快照因磁盘问题无法保存解决方案
  • 短视频网站如何做推广网站导航栏最多可以做几个
  • 做自由行的网站广告运营推广
  • 逆向爬虫——JavaScript混淆技术
  • 4.0 Labview中算法实例1-迟滞曲线上两段的平均差(拐点计算)
  • 网站建设数据库搭建西安广告设计制作公司
  • 作一手房用什么做网站有关学校网站建设策划书