这篇文章主要介绍“C++智能指针shared_ptr与右值如何引用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++智能指针shared_ptr与右值如何引用”文章能帮助大家解决问题。在 C++ 中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露。解决这个问题最有效的方法是使用智能指针(smart pointer)。智能指针是存储指向动态分配(堆)对象指针的类,用于生存期的控制,能够确保在离开指针所在作用域时,自动地销毁动态分配的对象,防止内存泄露。智能指针的核心实现技术是引用计数,每使用它一次,内部引用计数加1,每析构一次内部的引用计数减1,减为0时,删除所指向的堆内存。C++11 中提供了三种智能指针,使用这些智能指针时需要引用头文件:std::shared_ptr:共享的智能指针std::unique_ptr:独占的智能指针std::weak_ptr:弱引用的智能指针,它不共享指针,不能操作资源,是用来监视 shared_ptr 的。共享智能指针(shared_ptr)是指多个智能指针可以同时管理同一块有效的内存,共享智能指针 shared_ptr 是一个模板类,如果要进行初始化有三种方式:通过构造函数、std::make_shared 辅助函数以及 reset 方法。共享智能指针对象初始化完毕之后就指向了要管理的那块堆内存,如果想要查看当前有多少个智能指针同时管理着这块内存可以使用共享智能指针提供的一个成员函数 use_count实例调用拷贝构造函数调用移动构造函数如果使用拷贝的方式初始化共享智能指针对象,这两个对象会同时管理同一块堆内存,堆内存对应的引用计数也会增加;
如果使用移动的方式初始智能指针对象,只是转让了内存的所有权,管理内存的对象并不会增加,因此内存的引用计数不会变化。2.2.1 移动构造关于移动构造,可能有些读者不太明白移动构造是C++11标准中提供的一种新的构造方法。在现实中有很多这样的例子,我们将钱从一个账号转移到另一个账号,将手机SIM卡转移到另一台手机,将文件从一个位置剪切到另一个位置……移动构造可以减少不必要的复制,带来性能上的提升。我们首先来看看move函数
首先看这样一段代码输出的结果为再看这样一段代码其结果为这两段代码唯一的不同是调用vc.push_back()将字符串插入到容器中去时,第一段代码使用了move语句,而第二段代码没有使用move语句。输出的结果差异也很明显,第一段代码中,原来的字符串st已经为空,而第二段代码中,原来的字符串st的内容没有变化。先暂时记住这两端代码的输出结果之间的差异。
我们回到移动构造函数上有时候我们会遇到这样一种情况,我们用对象a初始化对象b,后对象a我们就不在使用了,但是对象a的空间还在呀(在析构之前),既然拷贝构造函数,实际上就是把a对象的内容复制一份到b中,那么为什么我们不能直接使用a的空间呢?这样就避免了新的空间的分配,大大降低了构造的成本。这就是移动构造函数设计的初衷。通俗一点的解释就是,拷贝构造函数中,对于指针,我们一定要采用深层复制,而移动构造函数中,对于指针,我们采用浅层复制。所以在上面的例子中,如果调用移动构造函数来初始化智能指针,引用计数是不会增加的,而move函数实际上是返回的右值引用2.2.2 右值引用上面我们讲到了右值引用,这里就来扩展一下右值引用是啥
首先得分清楚,什么是右值,什么是左值lvalue 是 loactor value 的缩写,rvalue 是 read value 的缩写左值是指存储在内存中、有明确存储地址(可取地址)的数据;右值是指可以提供数据值的数据(不可取地址);通过描述可以看出,区分左值与右值的便捷方法是:可以对表达式取地址(&)就免费云主机域名是左值,否则为右值 。所有有名字的变量或对象都是左值,而右值是匿名的。C++11 中右值可以分为两种:一个是将亡值( xvalue, expiring value),另一个则是纯右值( prvalue, PureRvalue):纯右值:非引用返回的临时变量、运算表达式产生的临时变量、原始字面量和 lambda 表达式等将亡值:与右值引用相关的表达式,比如,T&& 类型函数的返回值、 std::move 的返回值等。右值引用就是对一个右值进行引用的类型。因为右值是匿名的,所以我们只能通过引用的方式找到它。无论声明左值引用还是右值引用都必须立即进行初始化,因为引用类型本身并不拥有所绑定对象的内存,只是该对象的一个别名。通过右值引用的声明,该右值又“重获新生”,其生命周期与右值引用类型变量的生命周期一样,只要该变量还活着,该右值临时量将会一直存活下去。右值通过&&来引用例如:int&& value = 520;
里面 520 是纯右值,value 是对字面量 520 这个右值的引用。int &&a2 = a1;
中 a1 虽然写在了 = 右边,但是它仍然是一个左值,使用左值初始化一个右值引用类型是不合法的。const Test& t = getObj()
这句代码的语法是正确的,常量左值引用是一个万能引用类型,它可以接受左值、右值、常量左值和常量右值。通过 C++ 提供的 std::make_shared() 就可以完成内存对象的创建并将其初始化给智能指针,函数原型如下:实例
使用智能指针管理一块 int 型的堆内存, 内部引用计数为 1注意
使用 std::make_shared() 模板函数可以完成内存地址的创建,并将最终得到的内存地址传递给共享智能指针对象管理。如果申请的内存是普通类型,通过函数的()可完成地址的初始化,如果要创建一个类对象,函数的()内部需要指定构造对象需要的参数,也就是类构造函数的参数。共享智能指针类提供的 std::shared_ptr::reset 方法函数原型如下:ptr:指向要取得所有权的对象的指针d:指向要取得所有权的对象的指针aloc:内部存储所用的分配器实例对应基础数据类型来说,通过操作智能指针和操作智能指针管理的内存效果是一样的,可以直接完成数据的读写。但是如果共享智能指针管理的是一个对象,那么就需要取出原始内存的地址再操作,可以调用共享智能指针类提供的 get () 方法得到原始地址,其函数原型如下:实例当智能指针管理的内存对应的引用计数变为 0 的时候,这块内存就会被智能指针析构掉了。另外,我们在初始化智能指针的时候也可以自己指定删除动作,这个删除操作对应的函数被称之为删除器,这个删除器函数本质是一个回调函数,我们只需要进行实现,其调用是由智能指针完成的。实例删除器函数也可以是 lambda 表达式!关于“C++智能指针shared_ptr与右值如何引用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注百云主机行业资讯频道,小编每天都会为大家更新不同的知识点。
这篇文章主要介绍“switch分支语句怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“switch分支语句怎么使用”文章能帮助大家解决问题。分支语句完结撒花!!!switch这个分支语句没啥能讲的,加上个小练习加…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。