IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++新标准-C++11/14(第二讲:标准库部分) -> 正文阅读

[C++知识库]C++新标准-C++11/14(第二讲:标准库部分)

1. 标准库源码分布

在这里插入图片描述
在这里插入图片描述

2. Rvalue references

右值引用,按理来说应当属于语言的部分,但是由于它接下去都会和标准库有关,所以放入第二讲:
在这里插入图片描述
右值引用,为了解决不必要的copy和完美转发。
当赋值的右手边是一个右值,左手边(接受段)可以去偷右手边的resource,而不需要去执行allocation.
左值:可以出现在operator=的左侧
右值:只能出现在operator=的右侧
按理而言临时对象是一个右值,不能放在operator=的左侧,但是string和complex试验却产生了意想不到的结果,编译居然能通过。上图右边也有解释,我们不去关心这件事。
最重要两件事:临时对象是一个右值、右值只能出现在operator=的右侧。
再往下看:
在这里插入图片描述
上图函数返回的东西是一个右值,再取地址&就报错。

在这里插入图片描述
我们熟知的vector的insert是copy,但是2.0有了新的。
这里的例子会调用2,因为遇到了临时对象,是一个右值,则会调用右值引用的版本。
而所谓偷(move搬移)一开始就是浅拷贝,而浅拷贝是危险的,所以拷贝完会把原来的指针打断。这才是偷的精髓,即move之后原来的就会打断,就不能再使用了。
在例子中就是,原来这个右值Vtype(buf)临时对象,在move之后自身被打断,不能再用了,这很好,因为本身就是临时对象。
还有一种情况是,insert的是一个左值而不是临时对象,但是我很清楚之后不会再用他,那么我也可以让他走move这种方式。但是明明是左值想要走右值的路怎么办呢?
标准库于是给了std::move这样一个东西,只要把左值给进去就相当于拿到了它的Rvalue reference,就会走第二条路(move的路)

我的补充:关于智能指针

比如智能指针的unique_ptr也有move语义(偷的用法):
在这里插入图片描述

鼓励用std::make_unique<>():
在这里插入图片描述
比如下图,压根不用care前三个fun中指针的生命周期:
在这里插入图片描述

而对于shared_ptr:
在这里插入图片描述
shared_ptr在多线程场景用的比较多,而unique_ptr可能更常见于一些单线程的函数。语法上和unique_ptr大同小异,唯一区别是shared_ptr可以赋值,相当于拷贝,use_count+1,而use_count一变为0就立刻销毁,区别于一些语言的垃圾回收机制。
在这里插入图片描述
在这里插入图片描述
最后是weak_ptr:
所有的weak_ptr必须来自于shared_ptr,用lock函数会返回他的shared_ptr,暂时升级成shared_ptr,use_count++
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. Perfect Forwarding

源代码:
第一个版本G2.9是C++2.0之前的,只有一个版本。4.9即有两个版本。
在这里插入图片描述
再回到这张图:
在这里插入图片描述
这里用insert之后再交给MyString的move ctor去处理,经过了交接,会导致不完美。
在这里插入图片描述
在这里插入图片描述
用std::forward就会使用完美的快递,再往下看:
在这里插入图片描述
从这个例子我们可以看到,这里2明明是一个右值,但是forward(2)里面再调用process函数的时候却调用了process左值的版本,这便是不完美的转交。
原因是传入i之后,是一个具名变量named object
而从forward(move(a))也发现会出错。
所以要解决,这就是不完美的转发Unperfect Forwarding
下面是标准库的做法:
在这里插入图片描述

4. 写一个move aware class

可以看到move语义的时候一定要把原先的指针置为NULL(打断),否则原来的临时对象析构的时候就会把指针指向的东西析构掉,就会出错。
然后在析构的时候就要加if判断,指针非空去析构。
在这里插入图片描述
在这里插入图片描述

5. move aware class对容器效能的测试

如下,vector:一个放有move版本的,一个放没有的,测试结果效率差别很大。(有时候更是巨大的多)
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
最后发现,带不带move对于vector影响最大,对于deque在insert在中间某个地方要推(挤)影响就会很大,要是是在结尾加就不大。
下面再来讨论下图这个是为什么:
在这里插入图片描述
就是下图那三行:
在这里插入图片描述
第一个动作,真正的copy,当然慢:
在这里插入图片描述
第二个动作,把整个容器当作右值,那个容器的资源resource就被”偷”了,之后往下就不能用了:
在这里插入图片描述
而第三个动作,是因为一个vector内部是由三根指针刻画的,swap只交换三个指针速度当然快的不得了。

6. 容器结构与分类

下图是所有标准库的容器,红色的就是2.0新增加的:
在这里插入图片描述
在这里插入图片描述

7. 容器array

array其实就是一个C++的数组,只是包装成class的样子:
在这里插入图片描述
上图是2.9版比较简单,之后就变得很复杂了:
在这里插入图片描述

8. 容器hashtable

哈希表,或叫散列表,2.0之前其实也存在了,由hashtable之后做出了set和map,之后又实现了unordered的一些容器,即他们的底层都是hashtable:

在这里插入图片描述
篮子是由vector实现的(上图的buckets vector),篮子的个数会成长,底下引出的则是由链表实现的。
业界的一些规范:只要底下的链表数大于篮子数,就增大篮子数(扩增两倍),然后重来。如上图的再安插48个,6+48=54
而落在哪个篮子很简单:如108 % 53 = 2,108一开始就在第二号个篮子里,即mode篮子总数。
但是一般我们不会放整数,会放如对象,那么这里的108就是那个元素的代码,叫做hashcode。比如说字符串,就会有一个函数去计算一个字符串对应的代码,代码越乱越好减少冲突。
所以这样一个算出代码的函数就是hashfunction

9. unordered

2.0之后把hash改成了unordered:
在这里插入图片描述
在这里插入图片描述
篮子bucket个数永远大于元素个数,所以放100w个元素,篮子个数一定大于100w(因为等于的时候会扩充篮子)
当然,如果是set则要看不一样的值。
其实标准库里头已经把篮子个数算好了,一个例子:
在这里插入图片描述

10. hash function

下图,标准库有一些hash function,可以用来针对基本类型:
在这里插入图片描述
比如这里hash()就做了一个临时对象,是一个hash function,然后就可以当作函数继续调用:
hash()(123)
可以看到他们对应的hash code
看到G2.9版本的定义,就是模板的特化:
在这里插入图片描述
针对字符串,有下面这样的经验公式:
在这里插入图片描述
而2.9的时候对于浮点数都没有这样的hashfunction,而G4.9之后就有了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如上,有这么一些特化版本。
在这里插入图片描述
在这里插入图片描述
G4.9一路特化,调用了_Hash_bytes函数,只有声明没有定义,怀疑是编译已经放入二进制文件去了。

目前看到C++新标准-C++11/14 P31 Hash function
后续几小节找不到资源,下一步看STL

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-02 10:37:50  更:2021-08-02 10:40:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 5:44:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码