C++11 智能指针
C++ 11标准库引入了几种智能指针
unique_ptr
shared_ptr
weak_ptr
C++内存管理机制是当一个变量或对象从作用域过期的时候就会从内存中将他干掉。但是如果变量只是一个指针的话,干掉的就只是指针自身,而指针所指向的内存还是存在的,这就是所谓的内存泄漏。智能指针的出现就是为了解决这个问题。
智能指针的大体原理:当智能指针对象过期的时候,会执行智能指针对象的析构函数,在这里我们选择进行对所指堆对象的清除操作。
智能指针的头文件是
#include<memory>
定义在标准库命名空间 std 当中
其中:
unique_ptr是不允许复制操作的,所以一个unique_ptr不能直接赋值给另一个unique_ptr或者其他类型的智能指针。unique_ptr重载了->运算符可以直接寻找对应对象的
内容。它自始至终都是一个对象对应一个智能指针,绝对不允许把同一个对象赋值给两个unique_ptr指针,同时,一旦一个对象赋值给一个unique_ptr那么将不会有别的智能指针去被这个对象赋值。
如果我们想更改对象的赋值,我们智能使用std::move方法,这个方法废掉了原来的unique_ptr,使之变为无用的智能指针,然后赋值给一个新的智能指针。
shared_ptr则相反,它可以有很多个实例管理同一个堆对象,每增加一个实例,引用计数+1,过期一个实例,引用计数-1。当引用计数为0的时候释放堆内存。
weak_ptr不能直接用->获取对象的内容,需要调用lock()方法获得对象。此外使用方法和shared_ptr类似,但是不参与引用计数的计算。
接下来打算用一组实例来直观的反映一下智能指针的使用
#include<iostream>
#include<memory>
#include<string>
#include<functional>
using namespace std;
class poco_one
{
public:
poco_one(string n);
~poco_one();
public:
void showDesc();
private:
string name;
};
void testUniquePtr();
void testSharePtr();
void testWeakPtr();
int main()
{
testUniquePtr();
system("pause");
testSharePtr();
cout << "spc1 已经过期" <<endl;
system("pause");
testWeakPtr();
system("pause");
}
void testSharePtr()
{
cout << "测试share智能指针" << endl;
shared_ptr<poco_one> spc1(new poco_one("lily"));
cout << "当前引用计数为 : " << spc1.use_count() <<endl;
function<void(void)> func = [&]()
{
shared_ptr<poco_one> spc2 = spc1;
cout << "当前引用计数为 : " << spc1.use_count() << endl;
cout << "spc2 即将过期" <<endl;
};
func();
cout << "当前引用计数为 : " << spc1.use_count() <<endl;
cout << "spc2已过期"<<endl;
}
void testWeakPtr()
{
cout << "测试weak智能指针" << endl;
shared_ptr<poco_one> spc1(new poco_one("blaze"));
cout << "当前引用计数为 : " << spc1.use_count() << endl;
shared_ptr<poco_one> spc2 = spc1;
cout << "当前引用计数为 : " << spc1.use_count() << endl;
weak_ptr<poco_one> wpc = spc2;
cout << "当前引用计数为 : " << spc1.use_count() << endl;
wpc.lock()->showDesc();
}
void testUniquePtr()
{
cout << "测试unique智能指针"<<endl;
unique_ptr<poco_one> pcone1(new poco_one("rock"));
//unique_ptr<poco_one> pcone2 = pcone1; //无效 不可复制
pcone1->showDesc();
unique_ptr<poco_one> pcone3 = std::move(pcone1);
pcone1->showDesc();
pcone3->showDesc();
pcone3.reset();
pcone3->showDesc();
pcone1.reset(); //已经无效
unique_ptr<poco_one> pcone4;
pcone4->showDesc();
}
poco_one::poco_one(string n)
{
cout << "poco_one 对象已经被初始化" << endl;
name = n;
}
poco_one::~poco_one()
{
cout << "poco_one 对象即将被销毁" << endl;;
}
void poco_one::showDesc()
{
if (&name == NULL)
{
cout << "本对象已经被干掉或者不存在" << endl;
return;
}
cout << name + ":show something"<< endl;
}
其执行结果为:
测试unique智能指针 poco_one 对象已经被初始化 rock:show something 本对象已经被干掉或者不存在 rock:show something poco_one 对象即将被销毁 本对象已经被干掉或者不存在 本对象已经被干掉或者不存在 请按任意键继续. . . 测试share智能指针 poco_one 对象已经被初始化 当前引用计数为 : 当前引用计数为 : spc2 即将过期 当前引用计数为 : spc2已过期 poco_one 对象即将被销毁 spc1 已经过期 请按任意键继续. . . 测试weak智能指针 poco_one 对象已经被初始化 当前引用计数为 : 当前引用计数为 : 当前引用计数为 : blaze:show something poco_one 对象即将被销毁 请按任意键继续. . .
注:
C++类的成员方法即便不实例化对象也可以调用,同时智能指针也可以调用。但是如果动态成员变量没有初始值的话就会很危险!
lambda表达式如果用[=]复制的方式传参,那么这个复制出来的值要在lambda表达式所在的方法结束后才会过期,而不是lambda方法本身结束后过期。
C++11 智能指针的更多相关文章
- c++11 智能指针 unique_ptr、shared_ptr与weak_ptr
c++11 智能指针 unique_ptr.shared_ptr与weak_ptr C++11中有unique_ptr.shared_ptr与weak_ptr等智能指针(smart pointer), ...
- C++11——智能指针
1. 介绍 一般一个程序在内存中可以大体划分为三部分——静态内存(局部的static对象.类static数据成员以及所有定义在函数或者类之外的变量).栈内存(保存和定义在函数或者类内部的变量)和动态内 ...
- C++11智能指针之std::unique_ptr
C++11智能指针之std::unique_ptr uniqut_ptr是一种对资源具有排他性拥有权的智能指针,即一个对象资源只能同时被一个unique_ptr指向. 一.初始化方式 通过new云 ...
- 【C++11新特性】 C++11智能指针之weak_ptr
如题,我们今天要讲的是C++11引入的三种智能指针中的最后一个:weak_ptr.在学习weak_ptr之前最好对shared_ptr有所了解.如果你还不知道shared_ptr是何物,可以看看我的另 ...
- 详解C++11智能指针
前言 C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, weak_ptr 其中后三个是C++11支持,并且第一个已经被C++11弃用. C++11智能指针介 ...
- C++11智能指针
今晚跟同学谈了一下智能指针,突然想要看一下C++11的智能指针的实现,因此下了这篇博文. 以下代码出自于VS2012 <memory> template<class _Ty> ...
- C++11智能指针的深度理解
平时习惯使用cocos2d-x的Ref内存模式,回过头来在控制台项目中觉得c++的智能指针有点生疏,于是便重温一下.首先有请c++智能指针们登场: std::auto_ptr.std::unique_ ...
- C++11智能指针 share_ptr,unique_ptr,weak_ptr用法
0x01 智能指针简介 所谓智能指针(smart pointer)就是智能/自动化的管理指针所指向的动态资源的释放.它是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动 ...
- C++11智能指针原理和实现
一.智能指针起因 在C++中,动态内存的管理是由程序员自己申请和释放的,用一对运算符完成:new和delete. new:在动态内存中为对象分配一块空间并返回一个指向该对象的指针: delete:指向 ...
随机推荐
- 使用netty4.x客户端接收较大数据量报文时发生的读取不完整bug修复记录
1.先说问题 背景:服务是运行在Linux上的安全网关提供的,TCP协议发送 通过二进制编码的xml字符串 报文,报文头的第一个字段是int类型的表示字节序标记,第二个字段是int类型的表示整个报文长 ...
- spring相关jar包的含义
spring.jar是包含有完整发布的单个jar 包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到 spring-m ...
- Bootstrap 3 Datepicker 使用过程
最近在创建记录的时候,需要用到日历的功能.本身是使用的bootstrap布局的,所以就找到Datepicker,看了一下用起来还是挺方便的.下面就是使用过程. 依赖的资源 jQuery Moment. ...
- js 倒计时(可自定义时间)
<html> <head> <title>js 倒计时</title> </head> <body> <div> & ...
- What's the difference between <b> and <strong>, <i> and <em> in HTML/XHTML? When should you use each?
ref:http://stackoverflow.com/questions/271743/whats-the-difference-between-b-and-strong-i-and-em The ...
- Android study --- 广播
广播接收者 在Android系统运行时会产生很多事件,事件产生时,回想系统发送广播,只要向系统发送广播,系统就知道发生了相应的事件,从而执行相对应的代码.在系统中只要使用广播接受者,就可以接收广播 创 ...
- 对线程等待函数pthread_join二级指针参数分析
分析之前先搞明白,这个二级指针其实在函数内部是承接了上个线程的返回值. 看man手册,发现返回值是个普通指针.人家用二级指针来承接,可能准备干大事.这个可以自己搜索一下.原因嘛,二级指针是保存了这个地 ...
- mac终端命令大全介绍(转)
OSX 的文件系统 OSX 采用的Unix文件系统,所有文件都挂在跟目录 / 下面,所以不在要有Windows 下的盘符概念. 你在桌面上看到的硬盘都挂在 /Volumes 下. 比如接上个叫做 US ...
- ECMAScript toString() 方法
ECMAScript 定义所有对象都有 toString() 方法,无论它是伪对象,还是真对象. ECMAScript 的 Boolean 值.数字和字符串的原始值的有趣之处在于它们是伪对象,这意味着 ...
- linux的三种安装软件包的方式(小白的学习之旅)
tar包,整个安装过程可以分为以下几步: 1) 取得应用软件:通过下载.购买光盘的方法获得: 2) 解压缩文件:一般tar包,都会再做一次压缩,如gzip.bz2等,所以你需要先解压.如果是最常见的g ...