IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++实现MyString拓展 -> 正文阅读

[C++知识库]C++实现MyString拓展

String的写时拷贝

class String
{
protected:
	struct StrNode
	{
		int ref;
		int len;
		int size;
		char data[];
	};
private:
	StrNode* pstr;
public:
	String(const char* p = NULL)
	{
		if (p != NULL)
		{
			int sz = strlen(p);
			pstr = (StrNode*)malloc(sizeof(StrNode) + sz * 2 + 1);
			pstr->ref = 1;
			pstr->len = sz;
			pstr->size = sz * 2;
			strcpy(pstr->data, p);
		}
	}
	~String()
	{
		if (pstr != NULL && --pstr->ref == 0)
		{
			free(pstr);
		}
		pstr = NULL;
	}
	String(const String& str) :pstr(NULL)
	{
		if (str.pstr != NULL)
		{
			pstr = str.pstr;
			pstr->ref += 1;
		}
	}
	String& operator=(const String& s)
	{
		if (this == &s)return *this;
		if (this->pstr != NULL && --this->pstr->ref == 0)
		{
			free(this->pstr);
		}
		this->pstr = s.pstr;
		if (this->pstr != NULL)
		{
			this->pstr->ref += 1;
		}
		return *this;
	}

	char& operator[](const int index)
	{
		if (pstr == NULL)exit(0);
		assert(index >= 0 && index <= this->pstr->len - 1);
		if (pstr->ref == 1)
		{
			return pstr->data[index];
		}
		else
		{
			int total = sizeof(StrNode) + pstr->size + 1;
			StrNode* newnode = (StrNode*)malloc(total);
			memmove(newnode, pstr, total);
			newnode->ref = 1;
			pstr->ref -= 1;
			this->pstr = newnode;
			return pstr->data[index];
		}
	}
	const char& operator[](const int index)const
	{
		return (*const_cast<String*>(*this))[index];
		//常方法直接进行返回
		//去常性 使得常方法调用普通方法
	}   //s1[2]; //s1.operator[](2); //operator[](&s1,2)
	
	ostream& operator<<(ostream& out)const
	{
		if (pstr != NULL)
		{
			out << pstr->data;
		}
		return out;
	}
};

ostream& operator<<(ostream& out, const String& s)
{
	s << out;
	return out;
}

int main()
{
	String s1("123456");
	String s2(s1);

	String s3("hello");
	String s4(s3);

	s1[0] = 'x';
	cout << s2 << endl;

	return 0;
}

在这里插入图片描述
在这里插入图片描述

当我们需要对公用数组的多个对象中的一个进行修改的时候,需要创建空间进行深拷贝,使其独立成为一个新的对象,在进行修改

在我们调用常方法的[]运算符重载时,会发生常方法无法调用普通方法而导致的无限调用自身,return (*this)[index];而我们通过强制的手段,将this指针改为非常性使得正确调用普通方法

移动拷贝与移动赋值

String(String&& s):pstr(NULL)
{
	this->pstr = s.pstr;
	s.pstr = NULL;
}
String& operator=(String&& s)
{
	if (this != &s)
	{
		if (pstr != NULL && --pstr->ref == 0) //释放原本的空间
		{
			free(pstr);
		}
		this->pstr = s.pstr;
		s.pstr = NULL;
	}
	return *this;
}

写时拷贝的改进

每当我们通过调用中括号重载时 operator[](),都会产生新的空间,即使我们不需要改写,仅仅是进行获取

接下来我们对其进行改进

char operator[](const int index) const //仅取值
{
	assert(pstr != NULL && index >= 0 && index <= pstr->len-1);
	return pstr->data[index];
}
void modify(const int index, const char ch)//修改函数
{
	assert(pstr != NULL && index >= 0 && index <= pstr->len - 1);
	if (pstr->ref > 1)
	{
		int total = sizeof(StrNode) + pstr->size + 1;
		StrNode* newnode = (StrNode*)malloc(total);
		memmove(newnode, pstr, total);
		newnode->ref = 1;
		pstr->ref -= 1;
		this->pstr = newnode;
	}
	pstr->data[index] = ch;
}

添加修改函数来实现修改的需求

String加法重载

	const String operator+(const String& s)const
	{
	    //处理字符串为空,或其中一个为空的情况
		if (this->pstr == NULL && s.pstr == NULL)
		{
			return String();
		}
		else if (pstr != NULL && s.pstr == NULL)
		{
			return *this;
		}
		else if (pstr != NULL && s.pstr == NULL)
		{
			return s;
		}
		else
		{
			int total = (pstr->len + s.pstr->len) * 2;
			StrNode* newsp = (StrNode*)malloc(sizeof(StrNode) + total + 1);
			strcpy(newsp->data, pstr->data);
			strcat(newsp->data, s.pstr->data);
			newsp->ref = 1;
			newsp->len = pstr->len + s.pstr->len;
			newsp->size = total;

			return String(newsp); //创建一个私有特殊的构造函数
		}
	}

String加等重载

String& operator+=(const String& s)
{
	if (this->pstr != NULL && s.pstr != NULL)
	{
		if (this->pstr->ref > 1)
		{
			int total = this->pstr->len + s.pstr->len;
			this->pstr->ref -= 1;
			char* tmp = this->pstr->data;
			this->pstr = (StrNode*)malloc(sizeof(StrNode) + total * 2 + 1);
			strcpy(this->pstr->data, tmp);
			strcat(this->pstr->data, s.pstr->data);
			this->pstr->ref = 1;
			this->pstr->len = total;				this->pstr->size = total*2;
		}
		else //仅一个对象共享内存
		{
			if (this->pstr->size >= this->pstr->len + s.pstr->len)
			{
				strcat(this->pstr->data, s.pstr->data); //将s连接至this后面
				this->pstr->len = this->pstr->len + s.pstr->len;
			}
			else
			{
				int total = this->pstr->len + s.pstr->len;
				this->pstr = (StrNode*)realloc(this->pstr, sizeof(StrNode) + total * 2 + 1);//将内存追加至目标大小
				strcat(this->pstr->data, s.pstr->data);
				this->pstr->len = total;
			}
		}
		return *this;
	}
	if (s.pstr == NULL)
	{
		return *this;
	}
	else if (pstr == NULL && s.pstr != NULL)
	{
		pstr = s.pstr;
		pstr->ref += 1; // 将原本s的值 给到了this 会多出一个引用计数
		return *this;
	}
}

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-17 21:52:22  更:2022-03-17 21:54:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:05:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码