C++深浅拷贝和string类的两种写法详解

 更新时间:2022年03月10日 17:26:47   作者:平凡的指针  
这篇文章主要为大家详细介绍了C++深浅拷贝和string类的两种写法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

一、深浅拷贝

拷贝这个词对于我们来说应该不陌生,比如我们平常的复制和粘贴就是拷贝;但是如果把拷贝这个词放到C++中来说就有一些复杂了,我们先来看一下什么是浅拷贝:

下面用字符串类来模拟实现。

class Astring
{
public:
	//构造函数
	Astring(const char* str = "")
	{
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}
	//采用浅拷贝写的构造函数
	Astring(const Astring& s)
	{
		_str = s._str;
	}
	//析构函数
	~Astring()
	{
		delete[] _str;
		_str = nullptr;
	}
private:
	char* _str;
};
int main()
{
	Astring aa("hello C++");
	Astring bb(aa); //这里调用拷贝构造
	return 0;
}

当我们执行以上程序的话就会失败,结果如下:

在这里插入图片描述

分析如下图所示:

在这里插入图片描述

所以我们采用浅拷贝使用同一块空间是不行了,那么怎么办呢?当然是重新开一块和别人同样大小的空间,然后再把别人空间里面的内容给拷贝过来,而这样就是所谓的深拷贝了;我们还是用字符串类来模拟实现深拷贝:

class Astring
{
public:
	//构造函数
	Astring(const char* str = "")
	{
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}
	//采用深拷贝写的构造函数
	Astring(const Astring& s)
	{
		_str = new char[strlen(s._str) + 1];
		strcpy(_str, s._str);
	}
	//析构函数
	~Astring()
	{
		delete[] _str;
		_str = nullptr;
	}
private:
	char* _str;
};

int main()
{
	Astring aa("hello C++");
	Astring bb(aa);
	return 0;
}

分析如下图所示:

在这里插入图片描述

二、string类的两种写法

有了上面我们知道的深浅拷贝,所以我们明白类中的拷贝构造函数和赋值重载一定要用深拷贝来实现,不过拷贝构造函数和赋值重载还是有两种写法的。

1. 传统写法

传统写法就是要自己开辟空间自己来拷贝别人的东西,什么事情都要自己干,代码如下:

//搞一个命名空间,里面实现自己写的string类
namespace cjy
{
	class string
	{
	public:
		//构造函数
		string(const char* str = "")
			:_str(new char[strlen(str) + 1])
		{
			strcpy(_str, str);
		}
		//拷贝构造函数
		string(string& s)
			:_str(new char[strlen(s._str) + 1])
		{
			strcpy(_str, s._str);
		}
		//赋值重载,s1=s3
		string& operator=(const string& s)
		{
			if (this != &s)
			{
				char* tmp = new char[strlen(s._str) + 1];
				delete[] _str;
				_str = tmp;
				strcpy(_str, s._str);
			}
			return *this;
		}
		//析构函数
		~string()
		{
			delete[] _str;
			_str = nullptr;
		}
	private:
		char* _str;
	};
}

2. 现代写法

现代写法就是复用其它的函数,自己不用干活,交给其它函数来帮你实现,代码如下:

//现代写法:拷贝构造、赋值重载函数
namespace cjy
{
	class string
	{
	public:
		//构造函数
		string(const char* str = "")
		{
			_str = new char[strlen(str) + 1];
			strcpy(_str, str);
		}
		//拷贝构造函数
		string(const string& s)
			:_str(nullptr)
		{
			string tmp(s._str);
			std::swap(_str, tmp._str);
     	}
		//赋值重载
		string& operator=(string s)
		{
			std::swap(_str, s._str);
			return *this;
		}
	private:
		char* _str;
	};
}

分析如下图所示:

在这里插入图片描述

在这里插入图片描述

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容! 

相关文章

  • C++ Boost Accumulators累加器详细讲解

    C++ Boost Accumulators累加器详细讲解

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • 带你了解C++this指针的用法及其深究

    带你了解C++this指针的用法及其深究

    这篇文章主要介绍了C++中this指针的用法,对初学者而言是非常重要的概念,必须加以熟练掌握,需要的朋友可以参考下,希望能给你带来帮助
    2021-08-08
  • 解析C++多文件编程问题

    解析C++多文件编程问题

    在某些场景中,考虑到编译效率和可移植性,#pragma once 和 #ifndef 经常被结合使用来避免头文件被 重复引入,这里介绍用 _Pragma 操作符避免头文件重复引入的问题,感兴趣的朋友跟随小编一起看看吧
    2021-10-10
  • C语言简明介绍指针的使用

    C语言简明介绍指针的使用

    C语言这门课程在计算机的基础教学中一直占有比较重要的地位,然而要想突破C语言的学习,对指针的掌握是非常重要的,本文将具体针对指针的基础做详尽的介绍
    2022-06-06
  • C++实现字符串删除字符后逆序输出

    C++实现字符串删除字符后逆序输出

    这篇文章主要为大家详细介绍了C++实现字符串删除字符后逆序输出,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • C语言中带返回值的宏定义方式

    C语言中带返回值的宏定义方式

    这篇文章主要介绍了C语言中带返回值的宏定义方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • C++ LeetCode1769移动所有球到每个盒子最小操作数示例

    C++ LeetCode1769移动所有球到每个盒子最小操作数示例

    这篇文章主要为大家介绍了C++ LeetCode1769移动所有球到每个盒子所需最小操作数示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • vscode远程连接服务器(免密登录+远程开发)

    vscode远程连接服务器(免密登录+远程开发)

    vscode的远程连接功能十分方便,本文就来介绍一下vscode远程连接服务器,主要包括免密登录和远程开发,感兴趣的可以了解一下
    2024-07-07
  • C语言变长数组使用详解

    C语言变长数组使用详解

    这篇文章主要介绍了C语言变长数组使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • C语言入门篇--初识C语言及数据类型

    C语言入门篇--初识C语言及数据类型

    本篇文章是c语言基础篇,主要为大家介绍了C语言的基本类型,为大家介绍了什么是C语言,希望可以帮助大家快速入门c语言的世界,更好的理解c语言
    2021-08-08

最新评论