【C++】C++11——构造、赋值使用条件和生成条件

news2024/12/31 4:49:37

      • 移动构造和移动赋值生成条件
      • 移动构造和移动赋值调用逻辑
      • 强制生成默认函数的关键字default
      • 禁止生成默认函数的关键字delete

移动构造和移动赋值生成条件

C++11中新增的移动构造函数和移动赋值函数的生成条件为:

  • 移动构造函数的生成条件:没有自己实现的移动构造函数,并且没有自己实现的析构函数,拷贝构造函数和拷贝赋值函数。
  • 移动赋值函数的生成条件:没有自己实现的移动赋值函数,并且没有自己实现的析构函数,拷贝构造函数和拷贝赋值函数。

在这里,移动构造和移动赋值并不是说没有写就会自动生成,而是需要一定的条件支持下才会生成。

当我们实现了移动赋值函数和移动构造函数后,编译器就不会自动生成拷贝构造和拷贝赋值了

移动构造和移动赋值调用逻辑

默认生成的移动构造和移动赋值做的什么赋值

  • 默认生成的移动构造函数:对于内置类型来说,完成的为浅拷贝。如果存在自定义类型成员且实现了移动构造函数,这时就会调用自定义类型成员的移动构造函数。
  • 默认生成的移动赋值函数:对于内置类型来说,完成的为浅拷贝。如果存在自定义类型成员且实现了移动赋值函数,这时就会调用自定义类型成员的移动赋值函数。

下 面我们模拟实现以下,其中包括自定义string类和person类

namespace test
{
	class string
	{
	public:
		//构造函数
		string(const char* str = "")
		{
			_size = strlen(str); //初始时,字符串大小设置为字符串长度
			_capacity = _size; //初始时,字符串容量设置为字符串长度
			_str = new char[_capacity + 1]; //为存储字符串开辟空间(多开一个用于存放'\0')
			strcpy(_str, str); //将C字符串拷贝到已开好的空间
		}
		//交换两个对象的数据
		void swap(string& s)
		{
			//调用库里的swap
			::swap(_str, s._str); //交换两个对象的C字符串
			::swap(_size, s._size); //交换两个对象的大小
			::swap(_capacity, s._capacity); //交换两个对象的容量
		}
		//拷贝构造函数(现代写法)
		string(const string& s)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			cout << "string(const string& s) -- 深拷贝" << endl;

			string tmp(s._str); //调用构造函数,构造出一个C字符串为s._str的对象
			swap(tmp); //交换这两个对象
		}
		//移动构造
		string(string&& s)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			cout << "string(string&& s) -- 移动构造" << endl;
			swap(s);
		}
		//拷贝赋值函数(现代写法)
		string& operator=(const string& s)
		{
			cout << "string& operator=(const string& s) -- 深拷贝" << endl;

			string tmp(s); //用s拷贝构造出对象tmp
			swap(tmp); //交换这两个对象
			return *this; //返回左值(支持连续赋值)
		}
		//移动赋值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动赋值" << endl;
			swap(s);
			return *this;
		}
		//析构函数
		~string()
		{
			//delete[] _str;  //释放_str指向的空间
			_str = nullptr; //及时置空,防止非法访问
			_size = 0;      //大小置0
			_capacity = 0;  //容量置0
		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	};

	class Person
	{
	public:
		//构造函数
		Person(const char* name = "", int age = 0)
			:_name(name)
			, _age(age)
		{}
		拷贝构造函数
		//Person(const Person& p)
		//	:_name(p._name)
		//	, _age(p._age)
		//{}
		拷贝赋值函数
		//Person& operator=(const Person& p)
		//{
		//	if (this != &p)
		//	{
		//		_name = p._name;
		//		_age = p._age;
		//	}
		//	return *this;
		//}
		析构函数
		//~Person()
		//{}
	private:
		test::string _name; //姓名
		int _age;         //年龄
	};

}

从以上代码我们可以看出,我们person类中只有一个构造函数,这时是满足我们默认生成的条件的。

int main()
{
	test::Person s1("张三", 21);
	test::Person s2 = std::move(s1); //想要调用Person默认生成的移动构造

	return 0;
}

在这里插入图片描述
我们可以看出,此时输出的为移动构造,当我们将person类中的析构拷贝构造等复原的时候,这时就不满足条件了,也就调用的为深度拷贝了

强制生成默认函数的关键字default

在有一些条件下,我们的默认构造总是默认生成失败,为了解决这个问题,C++11推出了关键字default来强制将其生成。

class Person
{
public:
	Person() = default; //强制生成默认构造函数

	//拷贝构造函数
	Person(const Person& p)
		:_name(p._name)
		, _age(p._age)
	{}
private:
	cl::string _name; //姓名
	int _age;         //年龄
};

说明一下: 默认成员函数都可以用default关键字强制生成,包括移动构造和移动赋值。

禁止生成默认函数的关键字delete

当我们想要限制某些默认函数生成时,可以通过如下两种方式:

  • 在C++98中:我们可以直接将函数设置为私有,这样外部调用的时候就会直接报错。
  • 在C++11中,我们可以在函数声明的后面加上 =delete,表示让编译器不生成该函数的默认版本,我们将=delete修饰的函数称为删除函数。
class CopyBan
{
public:
	CopyBan()
	{}
private:
	CopyBan(const CopyBan&) = delete;
	CopyBan& operator=(const CopyBan&) = delete;
};

说明一下: 被=delete修饰的函数可以设置为公有,也可以设置为私有,效果都一样。

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

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

相关文章

Redis GEO 类型与 API 结合,地理位置优化的绝佳实践

&#x1f52d; 嗨&#xff0c;您好 &#x1f44b; 我是 vnjohn&#xff0c;在互联网企业担任 Java 开发&#xff0c;CSDN 优质创作者 &#x1f4d6; 推荐专栏&#xff1a;Spring、MySQL、Nacos、Java&#xff0c;后续其他专栏会持续优化更新迭代 &#x1f332;文章所在专栏&…

Linux下的网络编程——网络基础、socket编程(一)

前言&#xff1a; 前面我们学习了Linux的系统编程&#xff0c;从今天我们就要开始Linux网络编程的学习了&#xff0c;Linux网络编程中的知识点可能没有前面的Linux系统多一点&#xff0c;但是基础的网络知识我们还是需要了解的&#xff0c;并且网络编程中的socket编程的知识也…

打赏收款收银台多合一支付收款HTML源码

多合一打赏支付收款&#xff08;微信、QQ、支付宝&#xff09; 源码直接上传到服务器解压缩即可访问,或者用本地浏览器打开访问 PS&#xff1b;只需要将自己的收款二维码替换即可 该源码全开源无加密&#xff0c;所有操作均在本地无需调用外部资源防止失效&#xff01; 源码…

微前端架构的几种技术选型

微前端架构的几种技术选型随着SPA大规模的应用&#xff0c;紧接着就带来一个新问题&#xff1a;一个规模化应用需要拆分。 一方面功能快速增加导致打包时间成比例上升&#xff0c;而紧急发布时要求是越短越好&#xff0c;这是矛盾的。另一方面当一个代码库集成了所有功能时&am…

【校招VIP】java语言考点之反射

考点介绍&#xff1a; java的反射(reflection)机制是指在程序的运行状态中&#xff0c;可以构造任意一个类的对象&#xff0c;可以了解任意一个对象所属的类&#xff0c;可以了解任意一个类的成员变量和方法&#xff0c;可以调用任意一个对象的属性和方法。这种动态获取程序信息…

探索工业路由器如何助力无人驾驶方案的突破性解析

随着无人驾驶技术的发展&#xff0c;越来越多的企业和组织开始部署无人驾驶车辆来提高运输效率和安全性。在这些方案中&#xff0c;工业路由器被广泛应用于建立稳定、安全和高效的通信网络。在本篇文章中&#xff0c;我们将分享一个真实的无人驾驶方案部署案例&#xff0c;其中…

laravel设置与获取header请求头

laravel设置与获取header请求头 设置 <?phpnamespace App\Http\Controllers\Text;use Illuminate\Http\Request; use App\Http\Controllers\Controller;class TextController extends Controller {public function TextCC(Request $request){$token $request->header(j…

【函数进阶】

函数进阶 1 本节目标2 函数的定义和调用2.1 函数的定义方式2.2 函数的调用方式 3 this3.1 函数内 this 的指向3.2 改变函数内部 this 的指向3.2.1 call方法3.2.2 apply方法3.2.3 bind方法3.2.4 call apply bind 总结 4 严格模式4.1 什么是严格模式4.2 开启严格模式4.2.1 为脚本…

【校招VIP】交流技巧之面试时合理表达观点

考点介绍&#xff1a; 交流和表达是产品的面试最重要的考查点之一&#xff0c;也是产品必备工作技能。如果在面试中不能合理的与面试官沟通&#xff0c;或者不能把自己的思路和分析有逻辑的表达出来&#xff0c;都会对面试结果产生不好的影响。 交流技巧之面试时合理表达观点-…

【网络协议】Http-下

因为Http是无状态的&#xff0c;所以为了协助 Web 保持状态&#xff0c;Cookie 诞生了。 下面中是百度百科关于Cookie和Session的解释&#xff1a; Cookie&#xff1a;举例来说, 一个 Web 站点可能会为每一个访问者产生一个唯一的ID, 然后以 Cookie 文件的形式保存在每个用户的…

序列化 qmap

自定义的map不得行 但是qmap可以自己分配具体内存 这里没照完 待会照

通讯网关软件009——利用CommGate X2MQTT实现MQTT访问ODBC数据源

本文介绍利用CommGate X2MQTT实现MQTT访问ODBC数据源。CommGate X2MQTT是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;实现上位机通过MQTT来获取ODBC数据源的数据。 【解决方案】设置网关机…

「Qt中文教程指南」如何创建基于Qt Widget的应用程序(一)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文描述了如何使用…

【Java 并发编程】CopyOnWriterArrayList 详解

CopyOnWriterArrayList 详解 1. ArrayList1.1 ArrayList 和 LinkedList 的区别1.2 ArrayList 如何保证线程安全 2. CopyOnWriteArrayList 原理3. CopyOnWriteArrayList 的优缺点3.1 优点3.2 缺点 4. 源码分析4.1 两个成员变量4.2 构造函数4.3 add(E e)4.4 add(int index, E ele…

(总目录)springboot - 实现zip文件上传并对zip文件解压, 包含上传oss

全文目录,一步到位 1.本文概述1.1 本文简介 2. 功能实现2.1 统一文件校验2.2 普通(多)文件上传[服务器]2.2.1 controller层2.2.2 service层2.2.3 业务impl实现类2.2.4 FileIOUtils工具包代码 2.3 zip文件的解压2.4 图片文件的压缩2.5 oss文件后端上传2.6 oss文件前端上传2.7 后…

传统企业如何实现数字化转型?

传统企业实现数字化转型是一个复杂且多方面的过程&#xff0c;涉及将数字技术和战略融入业务的各个方面&#xff0c;以推动创新、效率和竞争力。以下是传统企业实现数字化转型可以遵循的步骤和策略&#xff1a; 1.领导层的认可和愿景&#xff1a; 首先要确保最高领导层&#x…

SpringCloud Gateway搭建Gateway 微服务应用实例

&#x1f600;前言 本篇博文是关于SpringCloud Gateway搭建Gateway 微服务应用实例&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您…

前端JavaScript入门到精通,javascript核心进阶ES6语法、API、js高级等基础知识和实战 —— JS基础(三)

思维导图 一、循环-for 1.1 for 循环-基本使用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport"…

scryptTS文档搜索功能上线!

在 scryptTS 文档中搜索 随着 scryptTS 文档的内容越来越丰富&#xff0c;从大量资料中快速定位感兴趣的部分变得越来越困难。 现在&#xff0c;你可以使用搜索功能&#xff0c;快速查找想了解的内容。

金蝶云星空与聚水潭对接集成物料查询连通商品上传(新)(物料主数据同步策略)

金蝶云星空与聚水潭对接集成物料查询连通商品上传&#xff08;新&#xff09;(物料主数据同步策略) 数据源系统:金蝶云星空 金蝶K/3Cloud结合当今先进管理理论和数十万家国内客户最佳应用实践&#xff0c;面向事业部制、多地点、多工厂等运营协同与管控型企业及集团公司&#x…