【C++】学习笔记——C++11_3

文章目录

  • 十九、C++11
    • 6. 右值引用和移动语义
      • 万能引用和完美转发
    • 7. 新的类功能
      • 新的默认成员函数
      • 类成员变量初始化
      • default
      • delete
      • 继承和多态中的final与override关键字
    • 8. 可变参数模板
      • STL容器中的empalce相关接口函数
  • 未完待续


十九、C++11

6. 右值引用和移动语义

万能引用和完美转发

模板中的&&不代表右值引用,而是万能引用,其既能接收左值又能接收右值。

#include <iostream>
using namespace std;template<typename T>
void PerfectForward(T&& t)
{cout << "PerfectForward(T&& t)" << endl;
}int main()
{// 右值PerfectForward(10);int a;// 左值PerfectForward(a);// 右值PerfectForward(move(a));const int b = 8;// const 左值PerfectForward(b);// const 右值PerfectForward(move(b));return 0;
}

在这里插入图片描述

无论是左值还是右值,都成功调用了函数模板。

模板的万能引用只是提供了能够接收同时接收左值引用和右值引用的能力,但是引用类型的唯一作用就是限制了接收的类型,后续使用中都退化成了左值。

#include <iostream>
using namespace std;void Fun(int& x)
{cout << "左值引用" << endl;
}
void Fun(const int& x)
{cout << "const 左值引用" << endl;
}
void Fun(int&& x)
{cout << "右值引用" << endl;
}
void Fun(const int&& x)
{cout << "const 右值引用" << endl;
}template<typename T>
void PerfectForward(T&& t)
{Fun(t);
}int main()
{// 右值PerfectForward(10);int a;// 左值PerfectForward(a);// 右值PerfectForward(move(a));const int b = 8;// const 左值PerfectForward(b);// const 右值PerfectForward(move(b));return 0;
}

在这里插入图片描述
这种情况该怎么办呢?我们希望能够在传递过程中保持它的左值或者右值的属性, 就需要用 完美转发forward

#include <iostream>
using namespace std;void Fun(int& x)
{cout << "左值引用" << endl;
}
void Fun(const int& x)
{cout << "const 左值引用" << endl;
}
void Fun(int&& x)
{cout << "右值引用" << endl;
}
void Fun(const int&& x)
{cout << "const 右值引用" << endl;
}// forward<T>(t)在传参的过程中保持了t的原生类型属性。
template<typename T>
void PerfectForward(T&& t)
{Fun(forward<T>(t));
}int main()
{// 右值PerfectForward(10);int a;// 左值PerfectForward(a);// 右值PerfectForward(move(a));const int b = 8;// const 左值PerfectForward(b);// const 右值PerfectForward(move(b));return 0;
}

在这里插入图片描述

7. 新的类功能

新的默认成员函数

原来C++类中,有6个默认成员函数:①构造函数②析构函数③拷贝构造函数④复制重载函数⑤取地址重载函数⑥const取地址重载函数。最重要的是前4个,后两个用处不大。默认成员函数就是我们不写编译器会生成一个默认的。
C++11 新增了两个默认成员函数:移动构造函数 和 移动赋值运算符重载。

如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个,那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝(浅拷贝),自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造。

如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个,那么编译器会自动生成一个默认移动赋值。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝(浅拷贝),自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。(默认移动赋值跟上面移动构造完全类似)

类成员变量初始化

现在类的成员变量可以在声明处给缺省值了。成员变量没初始化就会使用缺省值。

default

default 关键字可以 强制生成指定默认成员函数。比如:我们提供了拷贝构造,就不会生成移动构造了,那么我们可以使用default关键字显示指定移动构造生成。

#include <iostream>
#include <string>
using namespace std;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:string _name;int _age;
};int main()
{Person s1;Person s2 = s1;Person s3 = move(s1);return 0;
}

delete

delete 关键字可以 禁止生成指定默认成员函数。如果能想要限制某些默认函数的生成,在C++98中,是该函数设置成private,并且只声明补丁已,这样只要其他人想要调用就会报错。在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。

#include <iostream>
#include <string>
using namespace std;class Person
{
public:Person(const char* name = "", int age = 0):_name(name), _age(age){}// 禁止生成默认的拷贝构造函数Person(const Person& p) = delete;
private:string _name;int _age;
};int main()
{Person s1;Person s2 = s1;Person s3 = move(s1);return 0;
}

在这里插入图片描述

继承和多态中的final与override关键字

final可以修饰一个类,这个类会变成最终类,不能再被继承。
override可以修饰一个虚函数,强制虚函数进行重写,如果没有对这个虚函数进行重现,将会报错。

8. 可变参数模板

C++11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板。

// Args是一个模板参数包,args是一个函数形参参数包
// 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。
template <class ...Args>
void ShowList(Args... args)
{}

可变参数模板的原理是怎样的呢?可变参数模板是在 编译时递归处理参数包 的。

#include <iostream>
#include <string>
using namespace std;// 递归终止函数
template <class T>
void ShowList(const T& t)
{cout << t << endl;
}// 展开函数
template <class T, class ...Args>
void ShowList(T value, Args... args)
{cout << value << " ";ShowList(args...);
}int main()
{ShowList(1);ShowList(1, 'A');ShowList(1, 'A', string("sort"));return 0;
}

在这里插入图片描述

STL容器中的empalce相关接口函数

STL中empalce相关结构就使用了可变参数模板。
在这里插入图片描述
在这里插入图片描述
等等等。
确实这个函数跟普通的push系列函数功能都是一样的都是插入数据。

#include <iostream>
#include <string>
#include <list>
using namespace std;int main()
{list<pair<int, char>> list;// emplace系列是直接把参数当列表形式传入list.emplace_back(10, 'a');list.emplace_back(20, 'b');list.emplace_back(make_pair(30, 'c'));list.push_back(make_pair(40, 'd'));list.push_back({ 50, 'e' });for (auto e : list)cout << e.first << ":" << e.second << endl;return 0;
}

在这里插入图片描述
有区别的是:
push系列函数在对于深拷贝的对象进行插入时,会调用一次构造+一次移动构造,但是emplace系列仅仅只会调用一个构造函数,它是将参数一个一个传入对象的,省去了移动构造的消耗。
push系列函数对于浅拷贝的对象进行插入时,会调用一个构造+一次拷贝构造,但是emplace系列同理,将参数一个一个传入对象,也省去了拷贝构造的消耗,只会调用一次构造函数。

综上所述,对于深拷贝的对象,由于移动构造本身消耗就小,所以使用push系列或者emplace系列都可以;对于浅拷贝的对象,emplace则能够省去一个拷贝构造的消耗,优势还是蛮大的。所以建议使用emplace系列插入数据。


未完待续

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

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

相关文章

5 款最佳电脑照片恢复软件,助您恢复误删除的照片

电脑可以作为存储盒来保存您美好的照片记忆。 然而&#xff0c;病毒、格式化、删除等突发事件可能会夺走你由图片组成的记忆。 我怎样才能从我的计算机恢复已删除的照片&#xff1f; 照片恢复软件就是答案。 本页列出了适用于 Windows 和 Mac 的 5 个最佳图片恢复程序&…

创建个人公私钥对

Windows电脑 本地电脑打开命令输入框&#xff0c;如windows WINR–cmd打开cmd窗口输入ssh-keygen -t rsa -C “Remote dev” &#xff0c;按三次回车&#xff0c;即可看到本地生成的公私钥进入用户目录&#xff0c;如windows为C:\Users\xxx(个人域账号).ssh&#xff0c;可看到…

【股票价格跨度】python刷题记录

R3-栈和队列-单调栈 有个小思路&#xff1a;如果用栈的话&#xff0c;比如a,b在c前面&#xff0c;然后查找c的跨度的时候&#xff0c;往回搜索&#xff0c;如果b比c小&#xff0c;那就可以把b的跨度加到c上&#xff0c;否则&#xff0c;继续往回查找到a----&#xff08;思路貌似…

仿RabbitMQ实现消息队列———整体框架

目录 一、项目简介 需求分析 AMQP 特点&#xff1a; AMQP 模型&#xff1a; 交换机类型 持久化 网络通信 二、服务端模块 1、交换机数据管理 2、队列数据管理 3、绑定数据管理 4、消息数据管理 5、虚拟机数据管理 6、路由匹配管理 7、消费者管理 8、信道管理 …

BUGKU-WEB-文件包含

解题思路 你说啥我就干啥&#xff1a;点击一下试试你会想到PHP伪协议这方面去嘛&#xff0c;你有这方面的知识储备吗&#xff1f;看到?fileXXX.php&#xff0c;那不就是典型的文件包含吗&#xff1f;这里需要用的一个伪协议php://filter:是一种元封装器&#xff0c; 设计用于…

SSM学习10:整合MyBatis、MyBatisPlus

SpringBoot整合MyBatis 与创建spring web项目类型&#xff0c;添加上相应依赖 实体类 public class Account {private int id;public int getId() {return id;}public void setId(int id) {this.id id;}public String getName() {return name;}public void setName(String …

Educational Codeforces Round 168 (Rated for Div. 2)(A~D题题解)

A. Strong Password 思路&#xff1a;想要最长的时间&#xff0c;那么肯定就是如果存在前后相同的字母的时候&#xff0c;在中间插入一个不同的字符 &#xff0c;如果不存在前后相同的字符&#xff0c;直接在最后插入一个和原字符串最后一个字符不同的字符 #include <bits/…

Go语言入门进阶语法 | 数据结构 |指针|结构体|数组|切片|Map|方法|接口|错误|io库|泛型

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a; &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff0c;永远是个观众。…

QGIS 缓冲区交集信息提取

目标 计算出靠近河道的农田数量及位置&#xff0c;具体方法为使用QGIS 中计算出距离线图层&#xff08;代表河道&#xff09;100 米范围内的点&#xff08;代表水田&#xff09;图层中的点。 具体步骤 步骤 1: 创建缓冲区 首先需要基于线图层创建一个缓冲区图层。 打开 QGIS…

JavaScript基础——JavaScript调用的三种方式

JavaScript简介 JavaScript的作用 JavaScript的使用方式 内嵌JS 引入外部js文件 编写函数 JavaScript简介 JavaScript&#xff08;简称“JS”&#xff09;是一种具有函数优先的轻量级&#xff0c;解释型或即时编译型的编程语言。它是Web开发中最常用的脚本语言之一&#x…

软件测试:动态黑盒测试的过程

要成为一个成功的软件测试员&#xff0c;需要采用更结构化的、目标明确的方法继续测试。 本文粗略描述动态黑盒测试的结构化过程 目录 1.动态黑盒测试 拿到需求文档或产品说明书 定义测试用例 test-case 2. 通过性测试和时效性测试 3. 等价类划分 4. 数据测试 边界条件…

【Redis】 拓展:Redis - BigKey方案探讨

BigKey: 用户越多&#xff0c;redis数据越多&#xff0c;bigkey会使得缓存数据更大&#xff0c;网络带宽会被占用&#xff0c;执行效率就低下&#xff0c;高并发的时候吞吐量QPS也会下降。 产生原因&#xff1a; 看如下list&#xff1a; 一个key的内容太大&#xff0c;比如1M&…

【宝藏系列】物联网中常用的十种通信协议

【宝藏系列】物联网中常用的十种通信协议 文章目录 【宝藏系列】物联网中常用的十种通信协议1️⃣MQTT2️⃣CoAP3️⃣AMQP4️⃣XMPP5️⃣LwM2M6️⃣HTTP7️⃣DDS8️⃣Bluetooth Low Energy9️⃣LoRaWAN1️⃣0️⃣NB-IoT 1️⃣MQTT MQTT&#xff08;Message Queuing Telemetry T…

JNDI注入-高版本绕过

参考博客&#xff1a; JNDI注入与动态类加载 探索高版本 JDK 下 JNDI 漏洞的利用方法 - 跳跳糖 (tttang.com) 分析版本 jdk8u201 分析流程 修复 在ldap绕过中&#xff0c;我们讲了LDAP的修复&#xff0c;下面用jdk8u201具体来看下修复。 修复之前&#xff0c;利用是在L…

英文文献翻译方法哪个好?高效率的翻译方法分享

三伏天的酷热也抵挡不住学术人探索知识的脚步&#xff0c;阅读和翻译英文文献几乎已经成为了许多研究者和学者的日常。然而在面对浩如烟海的英文资料时&#xff0c;如何高效准确地进行翻译&#xff0c;成为了亟待解决的问题。 今天我便挖掘到了5款实用的英文文献翻译工具&…

【论文共读】【翻译】【GPT】Improving Language Understanding by Generative Pre-Training

GPT 原论文地址 翻译&#xff1a; Improving Language Understanding by Generative Pre-Training 通过生成式预训练提高语言理解能力 0. 摘要 自然语言理解包括各种不同的任务&#xff0c;例如文本蕴涵、问答、语义相似性评估和文档分类。尽管大量未标记的文本语料库很丰富…

《昇思25天学习打卡营第24天》

接续上一天的学习任务&#xff0c;我们要继续进行下一步的操作 构造网络 当处理完数据后&#xff0c;就可以来进行网络的搭建了。按照DCGAN论文中的描述&#xff0c;所有模型权重均应从mean为0&#xff0c;sigma为0.02的正态分布中随机初始化。 接下来了解一下其他内容 生成…

科普文:万字梳理高性能 Kafka快的8个原因

概叙 科普文&#xff1a;万字详解Kafka基本原理和应用-CSDN博客 科普文&#xff1a;万字梳理31个Kafka问题-CSDN博客 我们都知道 Kafka 是基于磁盘进行存储的&#xff0c;但 Kafka 官方又称其具有高性能、高吞吐、低延时的特点&#xff0c;其吞吐量动辄几十上百万。 在座的…

苹果safari历史记录如何恢复?4大秘籍,重访历史足迹

作为苹果设备上的默认浏览器&#xff0c;Safari为我们提供了便捷、快速的网页浏览体验。但是&#xff0c;如果出现意外删除或其他情况&#xff0c;我们可能会丢失Safari历史记录&#xff0c;这无疑给我们工作和学习带来了诸多不便。本文旨在帮助广大iPhone用户解决这一难题。通…

【音频识别】十大数据集合集,宝藏合集,不容错过!

本文将为您介绍10个经典、热门的数据集&#xff0c;希望对您在选择适合的数据集时有所帮助。 1 RenderMe-360 发布方&#xff1a; 上海人工智能实验室 发布时间&#xff1a; 2023-05-24 简介&#xff1a; RenFace是一个大规模多视角人脸高清视频数据集&#xff0c;包含多样的…