【C++】C++11--- 类的新功能

目录

类的新功能

默认成员函数

示例

类成员变量初始化

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

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


类的新功能

默认成员函数

  • 构造函数
  • 析构函数
  • 拷贝构造函数
  • 拷贝赋值重载
  • 取地址重载
  • const取地址重载

C++11在原先的6个默认成员函数的基础上,新增了2个:【移动构造函数】和【移动赋值运算符重载


默认移动构造的生成条件

条件1:开发者不显示实现移动构造函数;

条件2:析构函数、拷贝构造、赋值运算符重载函数任意一个都没有显示实现;

当同时满足条件1与条件2,编译器自动生成移动构造函数;

移动构造函数的规则

  • 移动构造函数对于内置类型成员按字节序完成值拷贝;
  • 移动构造函数对于自定义类型成员调用自定义类型的移动构造,若自定义类型成员没有移动构造,便调用其拷贝构造;

默认移动赋值的生成条件

条件1:开发者不显示实现移动赋值函数;

条件2:析构函数、拷贝构造、赋值运算符重载函数任意一个都没有显示实现;

当同时满足条件1与条件2,编译器自动生成移动赋值函数;

移动赋值函数的规则

  • 移动赋值函数对于内置类型成员直接赋值;
  • 移动赋值函数对于自定义类型成员调用自定义类型的移动赋值,若自定义类型成员没有移动赋值,便调用其赋值运算符重载函数;

开发者显示提供移动构造与移动赋值,编译器不再自动生成移动构造与移动赋值;

示例

namespace RightReference
{
	class string
	{
	public:
		typedef char* iterator;
		iterator begin()
		{
			return _str;
		}

		iterator end()
		{
			return _str + _size;
		}

		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			//cout << "string(char* str)" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, 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)
		{
			cout << "string(const string& s) --- 深拷贝" << endl;

			_str = new char[s._capacity + 1];
			strcpy(_str, s._str);
			_size = s._size;
			_capacity = s._capacity;
		}
		//移动构造--右值
		string(string&& s)
		{
			cout << "string(string&& s) -- 移动拷贝" << endl;
			swap(s);
		}
		// 拷贝赋值
		string& operator=(const string& s)
		{
			cout << "string& operator=(const string& s) --- 深拷贝" << endl;
			string tmp(s);
			swap(tmp);

			return *this;
		}
		// 移动赋值--右值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动拷贝" << endl;
			swap(s);

			return *this;
		}

		~string()
		{
			delete[] _str;
			_str = nullptr;
		}

		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}

		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;

				_capacity = n;
			}
		}

		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
				reserve(newcapacity);
			}

			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
		}

		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}

		const char* c_str() const
		{
			return _str;
		}
	private:
		char* _str = nullptr;
		size_t _size = 0;
		size_t _capacity = 0;
	};
}

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:
	RightReference::string _name;
	int _age;
};

int main()
{
	Person s1;
	Person s2 = s1;
	Person s3 = std::move(s1);
	Person s4;
	s4 = std::move(s2);
	return 0;
}

类成员变量初始化

默认生成的构造函数,对于自定义类型的成员会调用其构造函数进行初始化,但并不会对内置类型的成员进行处理;于是C++11支持非静态成员变量在声明时进行初始化赋值,默认生成的构造函数会使用这些缺省值对成员进行初始化;比如:

class Person
{
public:
	//...
private:
	//非静态成员变量,可以在成员声明时给缺省值
	RightReference::string _name = "peter";
	int _age = 20;
	static int _n; //静态成员变量不能给缺省值
};

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

C++11可以更好的控制要使用的默认成员函数,假设在某些情况下需要使用某个默认成员函数,但是因为某些原因导致无法生成这个默认成员函数,这时可以使用default关键字强制生成某个默认成员函数;

例如:我们提供了拷贝构造函数,就不会生成默认移动构造了,那么我们可以使用default关键字强制生成移动构造;

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(Person&& p) = default;
private:
	RightReference::string _name;
	int _age;
};

int main()
{
	Person s1;
	Person s2 = s1;
	Person s3 = std::move(s1);
	return 0;
}

例如:Person类中只实现了拷贝构造函数,没有实现构造函数,由于拷贝构造函数本身也是构造函数,默认构造不再自动生成;

class Person
{
public:
	
	//拷贝构造函数
	Person(const Person& p)
	:_name(p._name)
	,_age(p._age)
	{}
	
private:
	RightReference::string _name;
	int _age;
};

int main()
{
	Person s1;//error 没有合适的默认构造函数使用
	return 0;
}

此时可以使用default关键字强制生成默认的构造函数,如下:

class Person
{
public:
	Person() = default;
	//拷贝构造函数
	Person(const Person& p)
	:_name(p._name)
	,_age(p._age)
	{}
	
private:
	RightReference::string _name;
	int _age;
};

int main()
{
	Person s1;//error 没有合适的默认构造函数使用
	return 0;
}

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

C++98中,不期望某个类的对象被拷贝,得限制默认的拷贝构造函数的生成,一般的处理方式为将拷贝构造函数只声明不实现并且将此声明置于私有,如此外部调用时便会报错;

class Person
{
public:
	Person(const char* name=" ",int age=0)
		:_name(name)
		,_age(age)
	{}
private:
	//拷贝构造函数
	Person(const Person& p);

	RightReference::string _name;
	int _age;
};

int main()
{
	Person s1("Linda", 20);
	Person s2 = s1;//error
	return 0;
}

C++中只需要在拷贝构造函数的声明中加上=delete即可,该语法指示编译器不再生成拷贝构造函数的默认版本,称=delete修饰的函数为删除函数

class Person
{
public:
	Person(const char* name=" ",int age=0)
		:_name(name)
		,_age(age)
	{}

	//拷贝构造函数
	Person(const Person& p) = delete;

private:
	RightReference::string _name;
	int _age;
};

int main()
{
	Person s1("Linda", 20);
	Person s2 = s1;//error 尝试引用已删除的函数
	return 0;
}

欢迎大家批评指正,博主会持续输出优质内容,谢谢各位观众老爷观看,码字画图不易,希望大家给个一键三连支持~ 你的支持是我创作的不竭动力~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PHP基于vscode医院安全不良事件管理系统源码(AEMS)前端vue2+element+后端laravel8不良事件上报与闭环管理

PHP基于vscode医院安全不良事件管理系统源码&#xff08;AEMS&#xff09;前端vue2element后端laravel8不良事件上报与闭环管理 医院不良事件上报与管理系统结合现代医院管理思路&#xff0c;遵照PDCA全面质量循环管理方法而设计&#xff0c;并在多家大型三甲医院成熟运用。系统…

第29章-SR技术概述

1. SR技术的产生背景 2. SR技术的基本概念 3. SR技术的基本原理 1. SR技术的产生背景 1.1 传统的路由器设备因其转发性能较低 ① 最长匹配算法的缺点&#xff0c;需要遍历整个路由表&#xff1b; ② 早期路由器多采用通用CPU进行转发处理&#xff0c;性能有限&#xff1b; ③…

word:三线表的绘制【攻略】

word&#xff1a;三线表的绘制【攻略】 前言版权推荐word&#xff1a;三线表的绘制效果简单方法另外的方法 最后 前言 2024-5-7 18:25:08 以下内容源自《【攻略】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客…

Linux--基础IO(文件描述符fd)

目录 1.回顾一下文件 2.理解文件 下面就是系统调用的文件操作 文件描述符fd&#xff0c;fd的本质是什么&#xff1f; 读写文件与内核级缓存区的关系 据上理论我们就可以知道&#xff1a;open在干什么 3.理解Linux一切皆文件 4.C语言中的FILE* 1.回顾一下文件 先来段代码…

Upload-labs 靶场通关解析(上)

前言 文件上传漏洞是一种常见的网络安全漏洞&#xff0c;存在于许多Web应用程序中。攻击者利用这个漏洞可以上传恶意文件到目标服务器&#xff0c;从而执行各种恶意操作&#xff0c;如执行恶意代码、获取敏感信息、控制服务器等。 文件上传漏洞的原理是&#xff0c;Web应用程…

(✌)粤嵌—2024/5/7—除自身以外数组的乘积

代码实现&#xff1a; /*** Note: The returned array must be malloced, assume caller calls free().*/ int* productExceptSelf(int *nums, int numsSize, int *returnSize) {// 左乘积int l[numsSize];l[0] 1;for (int i 1; i < numsSize; i) {l[i] l[i - 1] * nums[…

PyQt6--Python桌面开发(1.安装配置环境)

一.PyQt6简介 PyQt&#xff1a;PyQt是一个功能强大且成熟的GUI框架&#xff0c;基于Qt库。它提供了丰富的组件、布局和主题选项&#xff0c;以及强大的功能和灵活性。PyQt的优点是它具有现代化的外观和丰富的功能&#xff0c;适用于复杂的GUI应用程序。然而&#xff0c;由于Py…

VMware导入ova/ovf虚拟机文件

1.文件-打开-ova文件 2.为新虚拟机起名称 3.等待导入 4.导入完成&#xff0c;可以开始使用 参考链接&#xff1a;VMware导入ova/ovf虚拟机文件

数仓分层——ODS、DW、ADS

一、什么是数仓分层 数据仓库分层是一种组织和管理数据仓库的结构化方法&#xff0c;它将数据仓库划分为不同的层次或级别&#xff0c;每个层次具有特定的功能和目的。这种分层方法有助于管理数据仓库中的数据流程、数据处理和数据访问&#xff0c;并提供一种清晰的结构来支持…

ArrayList线程安全问题解决方案

jdk8 Stream API的出现大大简化了我们对于集合元素的处理代码&#xff0c;对于串行流来说&#xff0c;无需考虑线程安全问题&#xff1b;但是&#xff0c;对于并行流来说&#xff0c;由于它是以多线程的方式并行处理同一个集合中的数据元素的&#xff0c;因此&#xff0c;存在着…

[Android]国内流行的应用市场

国内应用市场的特点 由于Google Play商店服务国内不可用&#xff0c;有许多其它的应用商店充当Android应用的分发渠道。这些商店通常由中国的主要科技公司运营&#xff0c;每个商店都有自己的运营策略和用户基础。 全球移动供应商市场份额&#xff1a;https://gs.statcounter…

我独自升级崛起PC下载安装教程 我独自升级崛起PC下载教程

《我独自升级&#xff1a;崛起》这款游戏灵感源自热门网络漫画《我独自升级》&#xff0c;是一款深度浸入式RPG游戏。它不仅呈献给玩家一个情节错综复杂、引人入胜的故事线&#xff0c;让玩家能紧随主角步伐&#xff0c;亲历其成长的点点滴滴&#xff0c;还自豪地展示了琳琅满目…

geojson文件规格

geojson文件示例&#xff0c; {"type": "FeatureCollection","features": [{"type": "Feature","geometry": {"type": "Point","coordinates": [102.0, 0.5]},"properties&q…

RT-DETR-20240507周更说明|更新Inner-IoU、Focal-IoU、Focaler-IoU等数十种IoU计算方式

RT-DETR改进专栏|包含主干、模块、注意力、损失函数等改进 专栏介绍 本专栏包含模块、卷积、检测头、损失等深度学习前沿改进,目前已有改进点70&#xff01;每周更新。 20240507更新说明&#xff1a; ⭐⭐ 更新CIoU、DIoU、MDPIoU、GIoU、EIoU、SIoU、ShapeIou、PowerfulIoU、…

聚乙烯醇(PVA)纳米纤维膜的性能介绍

聚乙烯醇&#xff08;PVA&#xff09;纳米纤维膜是一种由聚乙烯醇&#xff08;PVA&#xff09;分子组成的纳米级薄膜。这种材料具有许多优良的性能和应用前景&#xff0c;具体如下&#xff1a; 制备工艺&#xff1a;聚乙烯醇纳米纤维膜可以通过静电纺丝等方法制备。具体步骤包括…

网络知识点之—QoS

QoS&#xff08;Quality of Service&#xff0c;服务质量&#xff09;指一个网络能够利用各种基础技术&#xff0c;为指定的网络通信提供更好的服务能力&#xff0c;是网络的一种安全机制&#xff0c; 是用来解决网络延迟和阻塞等问题的一种技术。QoS的保证对于容量有限的网络来…

5000A信号发生器使用方法

背景 gnss工作需要使用的5000A&#xff0c;所以做成文档&#xff0c;用于其他员工学习。 下载星历数据 https://cddis.nasa.gov/archive/gnss/data/daily/2024/brdc/ 修改daily中的年份&#xff0c;就可以获取相关截至时间的星历数据 brcd数据格式 第一行记录了卫星的PRN号&a…

科创板门槛升级!解析中国量子企业的上市之路与国际比拼

4月30日晚&#xff0c;中国证监会于发布了修订后的《科创属性评价指引&#xff08;试行&#xff09;》&#xff08;以下简称“新指引”&#xff09;&#xff0c;该指引自发布日起正式生效。本次修订对原有指引中的部分标准进行了调整&#xff0c;具体如下&#xff1a; 1&#x…

远程桌面连接不上,远程桌面连接不上的专业解决策略

在信息技术领域&#xff0c;远程桌面连接是一种非常重要的工具&#xff0c;它允许用户从任何地点、任何时间访问和操作远程计算机。然而&#xff0c;当远程桌面连接出现问题时&#xff0c;可能会严重影响工作效率。以下是一些可能导致远程桌面连接不上的原因以及相应的解决方案…

干货分享-策划人都在用的活动策划网站

职场上&#xff0c;学会借力&#xff0c;学会‘抄’&#xff0c;比辛辛苦苦做老黄牛&#xff0c;更能事倍功半&#xff0c;不仅自己省事省力&#xff0c;还能获得更多升职加薪的机会。 那么&#xff0c;职场新人如何快速的写出一份领导满意的方案&#xff1f; 今天分享的‘抄…