C++Primer13.6.2节练习

news2024/11/17 11:27:22

练习13.49:

StrVec类的移动构造函数和移动赋值运算符

//移动构造函数
StrVec::StrVec(StrVec&& s)noexcept :elements(s.elements), first_free(s.first_free), cap(s.cap)
{
	//令移后源对象进入状态-----对其运行析构函数是安全的
	s.elements = s.first_free = s.cap = nullptr;
}

//移动赋值运算符
StrVec& StrVec::operator=(StrVec&& rhs)noexcept
{
	if (this != &rhs)
	{
		free();
		elements = rhs.elements;
		first_free = rhs.first_free;
		cap = rhs.cap;
		rhs.elements = rhs.first_free = rhs.cap = nullptr;
	}
	return *this;
}

String类的移动构造函数和移动赋值运算符

//移动构造函数
String::String(String&& s)noexcept:elements(s.elements),first_free(s.first_free),cap(s.cap)
{
	//令移后源对象进入状态-----对其运行析构函数是安全的
	s.elements = s.first_free = s.cap = nullptr;
}

//移动赋值运算符
String& String::operator=(String&& rhs)noexcept
{
	if (this != &rhs)
	{
		free();
		elements = rhs.elements;
		first_free = rhs.first_free;
		cap = rhs.cap;
		rhs.elements = rhs.first_free = rhs.cap = nullptr;
	}
	return *this;
}

Message类的移动构造函数和移动赋值运算符

void Message::move_Folders(Message* m)
{
	//使用set的移动赋值运算符
	folders = std::move(m->folders);
	//遍历每一个fFolder,从中删除旧的Message
	//将本Message添加到Folder中
	for (auto f : folders)
	{
		f->remMsg(m);
		f->addMsg(this);
	}
	//确保销毁m是无害的
	m->folders.clear();
}

//移动构造函数
Message::Message(Message&& m) :contents(std::move(m.contents))
{
	move_Folders(&m);
}

//移动赋值运算符
Message& Message::operator=(Message&& rhs)
{
	//检查自赋值情况
	if (this != &rhs)
	{
		//将本Message从所有的Folders中删除
		remove_from_Folders();
		//移动赋值
		contents = std::move(rhs.contents);
		//更新Folders
		move_Folders(&rhs);
	}

	return *this;
}

练习13.50:

向String类的移动构造函数和移动赋值运算符中添加打印语句

//移动构造函数
String::String(String&& s)noexcept:elements(s.elements),first_free(s.first_free),cap(s.cap)
{
	//令移后源对象进入状态-----对其运行析构函数是安全的
	s.elements = s.first_free = s.cap = nullptr;
	cout << "------String move constructor------" << endl;
}

//移动赋值运算符
String& String::operator=(String&& rhs)noexcept
{
	if (this != &rhs)
	{
		free();
		elements = rhs.elements;
		first_free = rhs.first_free;
		cap = rhs.cap;
		rhs.elements = rhs.first_free = rhs.cap = nullptr;
	}
	cout << "------String move assignment operator------" << endl;
	return *this;
}

测试代码

int main()
{
	//测试
	String s1("hello ");
	String s2("world!!!");
	String s3("C++");
	vector<String>vs;
	//移动构造
	String s4(std::move(s2));
	String s5(std::move(s1));

	//移动赋值运算符
	s2 = std::move(s3);
	system("pause");
	return 0;
}

结果

 练习13.51:

返回的是即将销毁的临时变量unique_ptr,是一个右值绑定的引用,所以这不是拷贝,而是移动,窃取资源而不是拷贝资源,所以是合法的

练习13.52:

在第一个赋值中,右侧运算对象是一个左值,因此移动构造函数是不可行的。rhs将使用拷贝构造函数来初始化。拷贝构造函数将分配一个新string,并拷贝 hp2指向的string
在第二个赋值中,我们调用std: : move 将一个右值引用绑定到hp2上。在此情况下,拷贝构造函数和移动构造函数都是可行的。但是,由于实参是一个右值引用,移动构造函数是精确匹配的。移动构造函数从hp2拷贝指针,而不会分配任何内存
不管使用的是拷贝构造函数还是移动构造函数,赋值运算符的函数体都swap两个运算对象的状态。交换HasPtr 会交换两个对象的指针(及int)成员。在swap 之后,rhs中的指针将指向原来左侧运算对象所拥有的 string。当rhs离开其作用域时,这个string将被销毁

练习13.53:

赋值运算符如下:


//赋值运算符既是移动赋值运算符,也是拷贝赋值运算符
HasPtr& HasPtr::operator=(HasPtr rhs)
{
	swap(*this, rhs);
	return *this;
}

对于拷贝赋值,首先要拷贝构造rhs(左值),然后swap

对于移动赋值,首先要移动构造rhs(右值),然后swap

都需要进行rhs的构造,性能不高

新的移动赋值运算符和移动构造函数如下

//拷贝赋值运算符
HasPtr& HasPtr::operator=(const HasPtr& rhs)
{
	if (this != &rhs)
	{
		delete ps;
		swap(*this, rhs);
	}
	return *this;
}


//移动赋值运算符
HasPtr& HasPtr::operator=(HasPtr&& rhs)noexcept
{
	if (this != &rhs)
	{
		delete ps;
		//移动元素
		ps = rhs.ps;
		i = rhs.i;
		rhs.ps = nullptr;
	}
	return *this;
}


练习13.54:

运行错误,产生二义性,传入的参数与两个函数都发生匹配

 

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

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

相关文章

关于网络编程

Socket套接字Socket API是网络编程最核心的部分。Socket套接字是由系统提供用于网络通信的技术&#xff0c;是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。Socket API与传输层密切相关&#xff0c;由于传输层有UDP和TCP两种协议类型…

使用Idea中将单个java类打包成jar包

开工第一天&#xff0c;正在暗自爽&#xff0c;领导让帮个忙&#xff0c;给一个工具类打成jar包&#xff0c;供其他项目组使用&#xff0c;这就开始了尝试。 其实网上已经有好多人写过了&#xff0c;只是尝试了几篇&#xff0c;坑得不轻&#xff0c;自己做下笔记&#xff0c;留…

表格控件Aspose.Cells for .NET 授权须知

支持的平台 Aspose.Cells 可作为 .NET、Java、C 和 Python 的四种不同产品使用&#xff0c; .NET Framework.NET Standard 2.0Xamarin.AndroidXamarin.iOSXamarin.MacCOMMonoWindows Azure Aspose.Cells 下载&#xff08;qun&#xff1a;761297826&#xff09;https://www.ev…

python 高阶函数

传入函数 要理解“函数本身也可以作为参数传入”&#xff0c;可以从Python内建的map/reduce函数入手。 我们先看map。map()函数接收两个参数&#xff0c;一个是函数&#xff0c;一个是序列&#xff0c;map将传入的函数依次作用到序列的每个元素&#xff0c;并把结果作为新的l…

Java:基于注解的Spring使用【AOP容器】和事务管理

目录 第十五章 AOP前奏15.1 代理模式15.2 为什么需要代理【程序中】15.3 手动实现动态代理环境搭建15.4 手动实现动态代理关键步骤第十六章 Spring中AOP【重点】16.1 AspectJ框架【AOP框架】16.2 使用AspectJ步骤&#xff08;入门&#xff09;16.3 Spring中AOP概述16.4 Spring中…

AMQP 0-9-1 模型解释

官方文档链接&#xff1a;https://www.rabbitmq.com/tutorials/amqp-concepts.html 文章目录1. AMQP协议是什么2. AMQP模型2.1 工作过程2.2 深入理解3. 交换机3.1 默认交换机3.2 直连交换机3.3 扇形交换机3.4 主题交换机3.5 头交换机3.6 交换机小结4. Queue队列队列属性队列创建…

BM7 链表中环的入口结点

目录 描述 输入描述&#xff1a; 返回值描述&#xff1a; 示例1 示例2 示例3 思路&#xff1a; 代码 描述 给一个长度为n链表&#xff0c;若其中包含环&#xff0c;请找出该链表的环的入口结点&#xff0c;否则&#xff0c;返回null。 例如&#xff0c;输入{1,…

DW 2023年1月Free Excel 第九次打卡 Excel数据透视

第九章 Excel数据透视 数据下载地址与参考链接&#xff1a;https://d9ty988ekq.feishu.cn/docx/Wdqld1mVroyTJmxicTTcrfXYnDd 数据透视是Excel中个强大的数据处理和分析工具&#xff0c;能够快速实现数据的汇总与统计分析&#xff0c;本节重点讲解Excel数据透视的相关操作。 1…

NSSCTF Round#7 Team ez_rce和0o0讲解

强烈建议NSSCTF延长时间&#xff0c;大过年的逛亲戚回来就剩两个小时了。。。。 ez_rce <!-- A EZ RCE IN REALWORLD _ FROM CHINA.TW --> <!-- By 探姬 --> <?PHPif(!isset($_POST["action"]) && !isset($_POST["data"]))show_s…

MySQL8中jdbc的url设置

JDBC spring.datasource.urljdbc:mysql://${MYSQL_HOST:localhost}:3306/xxxx?sslModeREQUIRED&characterEncodingUTF-8&connectionTimeZoneGMT%2B8&forceConnectionTimeZoneToSessiontruesslMode:设置为REQUIRED表示必须启用ssl加密传输&#xff1b;characterEn…

svn客户端add无法添加上子文件夹及其子文件——解决办法

1、问题描述 svn客户端add文件夹后&#xff0c;无法添加上子文件夹及其子文件&#xff0c;需要先add最外层文件夹&#xff0c;再逐层add子文件夹&#xff0c;最后add最里层子文件夹中的文件&#xff0c;很影响add速度啊。现象如下图所示&#xff1a; 正常情况下&#xff0c;add…

公派访问学者申请优势有哪些?

人的一生&#xff0c;若从职业生涯论&#xff0c;无非为官、为学、为商三条路。为官者&#xff0c;出国访学一年半载&#xff0c;对仕途并无太大作用&#xff0c;并且在此期间有可能丧失国内提拔的大好机会;为学者&#xff0c;公派访问学者是对学术水平的认可&#xff0c;并且对…

vue.js 实现导入json解析成动态el-table树表格(接口文档功能)

一、需求描述&#xff1a;前段时间接到一个需求是做一个类似接口文档的显示功能&#xff0c;将一段json数据贴到里面就可以自动解析出json数据的每个字段的类型和层级关系&#xff0c;用element组件的树表格的形式展示&#xff0c;并且可以手动新增、修改和删除某个数据字段。二…

Vue路由和路由器简介

前言 路由(route)是vue中非常重要的技术&#xff0c;几乎每一个用vue所写的项目都会用到路由&#xff0c;它是一个vue的插件库&#xff0c;专门实现SPA应用 路由(route)的简介 说到路由&#xff0c;大多数人会想到路由器(router),可以这么说&#xff0c;路由器上的每一个口都…

Python类变量和实例变量

类变量&#xff08;类属性&#xff09;类变量指的是在类中&#xff0c;但在各个类方法外定义的变量。举个例子&#xff1a;class CLanguage : # 下面定义了2个类变量name "CSDN社区"add "http://csdn.net" # 下面定义了一个say实例方法 defsay(self, conte…

【Linux】进程信号的产生与捕捉、核心转储

目录 一、信号的引入 二、信号捕捉 三、核心转储 四、系统调用发送信号 五、软件条件产生信号 六、硬件异常产生信号 一、信号的引入 Linux信号本质是一种通知机制&#xff0c;用户 or 操作系统通过发送一定的信号&#xff0c;通知进程&#xff0c;某些事件已经发生&…

JavaWeb-MyBatis | Mapper代理开发及案例

本专栏主要是记录学习完JavaSE后学习JavaWeb部分的一些知识点总结以及遇到的一些问题等&#xff0c;如果刚开始学习Java的小伙伴可以点击下方连接查看专栏 本专栏地址&#xff1a;&#x1f525;JDBC Java入门篇&#xff1a; &#x1f525;Java基础学习篇 Java进阶学习篇&#x…

【5G NTN】5G NTN(非地面组网)介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

DTD语法详细介绍

在编写XML文档时&#xff0c;需要掌握XML语法。同理&#xff0c;在编写DTD文档时&#xff0c;也需要遵循一定的语法。DTD的结构一般由元素类型定义、属性定义、实体定义、记号(notation)定义等构成&#xff0c;一个典型的文档类型定义会把将来要创建的XML文档的元素结构、属性类…

LeetCode Hot100 ---- 双指针算法专题

167, 88, 142, 76双指针双指针法&#xff0c;有时也叫快慢指针&#xff0c;在数组里是用两个整型值代表下标&#xff0c;在链表里是两个指针&#xff0c;一般能实现O(n)的时间解决问题&#xff0c;两个指针的位置一般在第一个元素和第二个元素或者第一个元素和最后一个元素&…