[C++] string类的介绍与构造的模拟实现,进来看吧,里面有空调

news2024/9/27 17:28:18

在这里插入图片描述

文章目录

  • 1、string类的出现
    • 1.1 C语言中的字符串
  • 2、标准库中的string类
    • 2.1 string类
  • 3、string类的常见接口说明及模拟实现
    • 3.1 string的常见构造
    • 3.2 string的构造函数
    • 3.3 string的拷贝构造
    • 3.4 string的赋值构造
  • 4、完整代码

1、string类的出现

1.1 C语言中的字符串

C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合面向对象的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
因此C++中,为了让我们更简单、方便、快捷的使用字符串类型,C++提供了string类。

2、标准库中的string类

2.1 string类

string类文档介绍
string类在使用的时候我们需要包含头文件 #include ,以及using namespace std;

  1. 字符串是表示字符序列的类。
  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。
  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
  5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

总结:
1. string是表示字符串的字符串类。
2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
3. string在底层实际是:basic_string模板类的别名,
typedef basic_string<char, char_traits, allocator>string;
4. 不能操作多字节或者变长字符的序列。

3、string类的常见接口说明及模拟实现

3.1 string的常见构造

(constructor)函数名称功能说明
string()构造空的string类对象,即空字符串
string(const char* s)用C-string来构造string类对象
string(size_t n, char c)string类对象中包含n个字符c
string(const string&s)拷贝构造函数
int main()
{
	string s1; // 构造空的string类对象s1
	string s2("hello"); // 用C格式字符串构造string类对象s2
	string s3(s2); // 拷贝构造s3

	return 0;
}

3.2 string的构造函数

namespace s
{
	class string
	{
	public:
    	//string()
		//	:_str(new char[1]{ '\0' })//这里开一个空间,并赋值为\0,如果直接赋值为nullptr的话
		//	,_size(0)				  //在实例化一个无参对象后,对对象进行操作的时候会引发空指针异常
		//	,_capacity(0)
		//{}
    
		//全缺省构造函数
		string(const char* str = "")//常量字符串默认以\0结尾,因此不需要给
			: _size(strlen(str))
			, _capacity(_size)
		{
			_str = new char[_capacity + 1];//多开一个空间,需要存放\0
			strcpy(_str, str);//将字符串拷贝到_str
		}

	private:
		char* _str;
		size_t _size;//有效存储字符个数
		size_t _capacity;//实际空间
	};
}

这里我们用一个全缺省将无参构造与构造都包括了。
这个构造函数很简单,这里就不多讲了,大家应该可以看懂。

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);
}
//现代写法 s1(s2)
string(const string& s)
    :_str(nullptr)
    ,_size(0)
    ,_capacity(0)
{
    string tmp(s._str);//构造
    swap(tmp);//this->swap(s);
}

库里提供了交换函数,我们封装一个交换函数,内部的实现就使用库里面的swap,我们拷贝构造函数里面先调用构造函数,实例化一个tmp,再将tmp与this交换。

3.4 string的赋值构造

传统写法:

string& operator=(const string& s)
{
	if (this != &s)
	{
		string tmp(s);//拷贝构造
		swap(tmp);
	}
	return *this;
}

现代写法:这里与拷贝构造的现代写法是类似的,不再多说。

void swap(string& s)
{
    std::swap(_str, s._str);
    std::swap(_size, s._size);
    std::swap(_capacity, s._capacity);
}
string& operator=(const string& s)
{
    if (this != &s)
    {
        string tmp(s);//拷贝构造
        swap(tmp);
    }
    return *this;
}

我们其实可以对现代写法继续精简一下,我们这里参数是引用传参,我们不用引用就会产生一次拷贝,对拷贝的形参直接进行交换,这样就可以简化写法,但是这里的效率其实是一样的,都是一次拷贝构造 + 一次交换。

// 极致写法,效率与上面一样
string& operator=(string tmp)//参数直接调用拷贝构造
{
    swap(tmp);

    return *this;
}

4、完整代码

#include <string.h>
#include <algorithm>
using namespace std;

namespace s
{
	class string
	{
	public:
		//string()
		//	:_str(new char[1]{ '\0' })//这里开一个空间,并赋值为\0,如果直接赋值为nullptr的话
		//	,_size(0)				  //在实例化一个无参对象后,对对象进行操作的时候会引发空指针异常
		//	,_capacity(0)
		//{}

		//全缺省构造函数
		string(const char* str = "")//常量字符串默认以\0结尾,因此不需要给
			:_size(strlen(str))
			,_capacity(_size)
		{
			_str = new char[_capacity + 1];//多开一个空间,需要存放\0
			strcpy(_str, str);//将字符串拷贝到_str
		}

		//拷贝构造
		// 传统写法
		//string(const string& s)
		//	:_size(s._size)
		//	,_capacity(s._capacity)
		//{
		//	_str = new char[s._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);
		}
		//现代写法 s1(s2)
		string(const string& s)
			:_str(nullptr)
			,_size(0)
			,_capacity(0)
		{
			string tmp(s._str);//构造
			swap(tmp);//this->swap(s);
		}

		//赋值
		// 传统写法
		//string& operator=(const string& s)
		//{
		//	if (this != &s)
		//	{
		//		char* tmp = new char[s._capacity];
		//		strcpy(tmp, s._str);

		//		delete[] _str;
		//		_str = tmp;//将tmp字符串直接给_str,类似浅拷贝
		//		_size = s._size;
		//		_capacity = s._capacity;
		//	}

		//	return *this;
		//}

		//现代写法
		//string& operator=(const string& s)
		//{
		//	if (this != &s)
		//	{
		//		string tmp(s);//拷贝构造
		//		swap(tmp);
		//	}
		//	return *this;
		//}
		// 极致写法,效率与上面一样
		string& operator=(string tmp)//参数直接调用拷贝构造
		{
			swap(tmp);

			return *this;
		}

		~string()
		{
			cout << "~string()" << endl;
			delete[] _str;
			_size = _capacity = 0;
		}

	private:
		char* _str;
		size_t _size;//有效存储字符个数
		size_t _capacity;//实际空间
	};
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/889525.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【宝藏系列】嵌入式 C 语言代码优化技巧【超详细版】

【宝藏系列】嵌入式 C 语言代码优化技巧【超详细版】 文章目录 【宝藏系列】嵌入式 C 语言代码优化技巧【超详细版】前言整形数除法和取余数合并除法和取余数通过2的幂次进行除法和取余数取模的一种替代方法使用数组下标全局变量使用别名变量的生命周期分割变量类型局部变量指针…

Lnton羚通关于如何使用OpenCV-Python在直方图中查找显示分析

什么是直方图&#xff1f; 直方图是统计图像中像素亮度或颜色等分布的一种常用工具&#xff0c;几乎所有图像处理的工具都提供了这种工具&#xff0c;X轴表示 0~255&#xff08;刻度大小与Bin设置有关系&#xff09;&#xff0c;Y轴统计个数&#xff08;频率&#xff09;。 【…

VIOOVI:标准的作业规范要求是什么?标准化作业规范怎么写?

本文围绕“标准化作业”展开论述&#xff0c;分享一些关于标准化作业以及标准的作业规范等相关知识。 什么是标准化作业&#xff1f; 标准化作业是一种以人的行为为中心&#xff0c;在一个操作序列中有效地进行生产而没有浪费的操作方法。 标准化作业的前提即&#xff1a;关注…

从零开始打造家装预约咨询小程序

在如今互联网高度发达的时代&#xff0c;家装行业也逐渐意识到了线上渠道的重要性。为了更好地服务客户&#xff0c;提高用户体验&#xff0c;越来越多的家装公司开始寻找合适的小程序制作平台。本文将向大家介绍如何使用第三方制作平台&#xff0c;如乔拓云网&#xff0c;打造…

Android 9.0 Vold挂载流程解析(上)

Android 9.0 Vold挂载流程解析&#xff08;上&#xff09; 前言Android挂载模块整体框架Vold进程main函数详细分析总结 前言 我们分2篇文章来介绍Android 9.0中存储卡的挂载流程&#xff0c;本篇文章先介绍总体的挂载模块、Vold进程的入口main函数的详细分析&#xff0c;有了这…

文心一言最新重磅发布!

8月16日&#xff0c;由深度学习技术及应用国家工程研究中心主办的WAVE SUMMIT深度学习开发者大会2023举办。百度首席技术官、深度学习技术及应用国家工程研究中心主任王海峰以《大语言模型为通用人工智能带来曙光》为题&#xff0c;阐述了大语言模型具备理解、生成、逻辑、记忆…

C++新经典01--函数递归

函数的递归 #include <stdio.h> void diguifunc() {printf("diguifunc()函数执行\n");diguifunc();//自己调用自己 }void main(){diguifunc(); }把程序执行起来&#xff0c;等几秒钟&#xff0c;可以看到&#xff0c;屏幕不断滚动并输出如下内容&#xff1a; …

通过cpolar分享本地电脑上有趣的照片:部署piwigo网页【无公网IP内网穿透】

在强者的眼中&#xff0c;没有最好&#xff0c;只有更好。我们是移动开发领域的优质创作者&#xff0c;同时也是阿里云专家博主。 ✨ 关注我们的主页&#xff0c;探索iOS开发的无限可能&#xff01; &#x1f525;我们与您分享最新的技术洞察和实战经验&#xff0c;助您在移动应…

如何在pycharm中指定GPU

如何在pycharm中指定GPU 作者:安静到无声 个人主页 目录 如何在pycharm中指定GPU打开编辑配置点击环境变量添加GPU配置信息推荐专栏在Pycharm运行程序的时候,有时候需要指定GPU,我们可以采用以下方式进行设置: 打开编辑配置 点击环境变量 添加GPU配置信息 添加名称:CU…

【C++学习手札】一文带你初识C++继承

食用指南&#xff1a;本文在有C基础的情况下食用更佳 &#x1f340;本文前置知识&#xff1a; C类 ♈️今日夜电波&#xff1a;napori—Vaundy 1:21 ━━━━━━️&#x1f49f;──────── 3:23 …

unity物体移动至指定位置

物体坐标与物体移动 世界坐标与局部坐标之间的转换物体移动至指定位置需求思路注意 世界坐标与局部坐标之间的转换 在Unity中&#xff0c;物体的坐标分为局部坐标和世界坐标。 局部坐标是相对于物体的父对象的坐标系&#xff0c;而世界坐标是相对于场景的整体坐标系。 使用tr…

一个DW的计算

一个DW的计算 1- 题目: 已知一个DW1.1 要求: 从DW中取出指定的位的值1.1.1 分析1.1.2 实现1.1.3 简化实现1.1.4 验证 2- 题目: 已知一个DW2.1 要求: 从DW中的指定的P和S,取出指定的位的值2.1.1 分析2.1.2 实现 1- 题目: 已知一个DW 有图中所示一行信息&#xff0c;表示一个DW(…

mktime有时会返回-1使用boost库没有问题

linux获得时间戳 #include <iostream> #include <boost/date_time/posix_time/posix_time.hpp> long long utc8_to_stamp(int date, float time) {struct tm stm;int itime (time);int iY date/10000,iM(date-iY*10000)/100,iDdate%100,iHitime/10000,iMin(itime…

学习笔记十七:node节点选择器,亲和性

node节点选择器&#xff0c;污点、容忍度、亲和性 node节点选择器nodeName&#xff0c;指定pod节点运行在哪个具体node上nodeSelector&#xff1a;指定pod调度到具有哪些标签的node节点上 亲和性node节点亲和性使用requiredDuringSchedulingIgnoredDuringExecution硬亲和性使用…

Linux编程库

1、Linux编程库介绍&#xff1a; 编程库就是指始终可以被多个Linux软件项目重复使用的代码集。 使用编程库有两个主要的优点&#xff1a; 可以简化编程&#xff0c;实现代码重复使用&#xff0c;进而减小应用程序的大小。可以直接使用比较稳定的代码。 Linux下的库文件分为共…

rabbitmq容器启动后修改连接密码

1、进入容器 docker exec -it rabbitmq bash 2、查看当前用户列表 rabbitmqctl list_users 3、修改密码 rabbitmqctl change_password [username] ‘[NewPassword]’ 4、修改后退出容器 ctrlpq 5、退出容器后即可生效&#xff0c;不需要重启容器

三分之一的英国大学生被欺诈

根据NatWest的一项新研究&#xff0c;去年英国大学三分之一的学生在网上遭遇欺诈。 今年5月&#xff0c;这家高街银行委托咨询公司RedBrick对来自63个城镇的3000多名英国大学生进行了调查。 尽管三分之一的受访者表示他们在过去的12个月里遇到过诈骗&#xff0c;但没有统计数…

动手学深度学习-pytorch版本(二):线性神经网络

参考引用 动手学深度学习 1. 线性神经网络 神经网络的整个训练过程&#xff0c;包括: 定义简单的神经网络架构、数据处理、指定损失函数和如何训练模型。经典统计学习技术中的线性回归和 softmax 回归可以视为线性神经网络 1.1 线性回归 回归 (regression) 是能为一个或多个…

【06 英语语法:时态、语态、虚拟语气】

时态、语态、虚拟语气 1. 时态和语态1.1 时态: 4个时间*4个状态 &#xff08;时间&#xff1a;现在、过去、将来、过去将来&#xff1b;状态&#xff1a;一般、进行、完成、完成进行&#xff09;⑴ 16 时态 详解表⑵ 主从句的 时态搭配⑶ 常用的 不规则动词变化 1.2 语态&#…

url下载地址含非法字符下载失败

示例下载链接&#xff1a;https://666666.shei.org.cn:2023/20230105/0ac280a3-498b-45d8-830c-a788475a8022/2023817-F2666666很六 &#xff08;改&#xff09;.doc java.lang.IllegalArgumentException: Illegal character in path at index 96: https://666666.shei.org.c…