C++2.0新特性(六)——<Smart Pointer(智能指针)之shared_ptr>
Smart Pointer(智能指针)指的是一类指针,并不是单一某一个指针,它能知道自己被引用的个数以至于在最后一个引用消失时销毁它指向的对象,本文主要介绍C++2.0提供的新东西
一、Smart Pointer分类
C++2.0提供了两大类型的智能指针,该模块都被定义于头文件<memory>:

二、标准库提供的智能指针类
2.1 class shared_ptr
提供了共享式拥有语义,也就是说当对个shared_ptr可以共享(或拥有)同一个对象,对象的最后一个拥有者有责任销毁对象,并清理与该对象相关的所有资源,也就是说它所指向的对象不再被需要时,自动释放(当超出作用域时,其析构函数被调用,在析构函数中,将其引用计数减1,如果引用计数的值变为0,则删除关联的原始指针,默认使用delete释放内存)与对象相关的资源。
2.2 shared_ptr使用
可以像其他任何指针一样使用,可以赋值、拷贝、比较它们也可以使用*和->操作符访问所指向的内容
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std; int main()
{
// two shared pointers representing two persons by their name
shared_ptr<string> pNico(new string("nico"));//shared_ptr<string> pNico = make_shared<string>("nico");
shared_ptr<string> pJutta(new string("jutta"));//注意,直接这种形式的构造表示这个构造函数是explicit // capitalize person names
(*pNico)[] = 'N';
pJutta->replace(, , "J"); // put them multiple times in a container
vector<shared_ptr<string>> whoMadeCoffee;//此处放进去的是指针的引用,不是指针的内容
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pNico);
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pNico); // print all elements
for (auto ptr : whoMadeCoffee) {
cout << *ptr << " ";
}
cout << endl; // overwrite a name again
*pNico = "Nicolai"; // print all elements again
for (auto ptr : whoMadeCoffee) {
cout << *ptr << " ";
}
cout << endl; // print some internal data
cout << "use_count: " << whoMadeCoffee[].use_count() << endl;
//use_count 返回第一个元素被引用的次数,容器里面的三个拷贝和自身,加起来为4
}

2.2 shared_ptr自定义析构函数
再上图例子中,如果我们想自己定义析构函数的规则,不想用string*默认的,那我们就需要在构造时增加一点改动:
传递一个lambda作为shared_ptr构造函数的第二实参,这样申明的方式当其最末一个拥有者被摧毁时,会调用这个lambda
shared_ptr<string> pNico(new string("nico"), [](string* p) {
cout << "delete" << *p << endl;
delete p; });

2.3 shared_ptr对于数组的使用
一般我们使用shared_ptr的时候没有指定其析构函数,是因为shared_ptr有一个默认的析构函数,这个默认的析构函数调用的是delete函数,这就意味着shared_ptr拥有的是由new建立起来的单一对象时,default delete才能适用,但是当我们使用数组的时候(数组需要delete[]),这个默认的delete就不适用了,我们需要自己定义delete.
std::shared_ptr<int> p(new int[], [](int *p) {delete[] p; });
也可使用编译器为unique_ptr提供的辅助函数作为deleter析构策略:
std::shared_ptr<int> p(new int[], std::default_delete<int[]>());
注意:shared_ptr不提供operator [],只提供operator*和operator->,想访问内存,必须使用get()函数来获取被shared_ptr包裹的内部指针;
2.4 shared_ptr析构策略
当shared_ptr的最后一个声明周期结束后,如果清理工作不仅仅是删除内存,这时你必须明确给出自己的deleter,可以指定属于自己的析构策略。
下例展示:当指向临时文件的的最后一个引用消失时,我们要删除这个文件
#include <string>
#include <fstream> // for ofstream
#include <memory> // for shared_ptr
#include <cstdio> // for remove() class FileDeleter
{
private:
std::string filename;
public:
FileDeleter (const std::string& fn)
: filename(fn) {
std::cout << "constructor" << std::endl;
}
void operator () (std::ofstream* fp) {
std::cout << "delete" << std::endl;
delete fp; // close file
std::remove(filename.c_str()); // delete file 删除文件
}
}; int main()
{
// create and open temporary file:
//这里会创建一个shared_ptr指针,令他指向new新建的输出文件,FileDeleter将负责shared_ptr的最后一个拷贝失去此输出文件的所有权时进行一系列清理操作
std::shared_ptr<std::ofstream> fp(new std::ofstream("tmpfile.txt"),
FileDeleter("tmpfile.txt"));
//解释上一行的运行原理:首先new时会产生一个临时对象,FileDeleter("tmpfile.txt")也会产生一个临时对象,当析构时,会将new的临时对象传给FileDeleter,即调用()运算符
std::cout << "reset" << std::endl;
fp.reset();
std::cout << "reset end" << std::endl;
//... }

2.5 常见成员函数以及分类介绍




C++2.0新特性(六)——<Smart Pointer(智能指针)之shared_ptr>的更多相关文章
- C++2.0新特性(八)——<Smart Pointer(智能指针)之unique_ptr>
一.概念介绍 unique_ptr它是一种在异常发生时可帮助避免资源泄露的smart pointer,实现了独占式拥有的概念,意味着它可确保一个对象和其他相应资源在同一时间只被一个pointer拥有, ...
- C++2.0新特性(七)——<Smart Pointer(智能指针)之weak_ptr>
一.weak_ptr出现的意义 上一节提到过shared_ptr,它会自动释放“不再需要使用的对象”的相应的资源,但是它不是万能的,在某些时候(比如说循环引用),它会显得力不从心,这就是weak_pt ...
- 【C++11新特性】 C++11智能指针之shared_ptr
C++中的智能指针首先出现在“准”标准库boost中.随着使用的人越来越多,为了让开发人员更方便.更安全的使用动态内存,C++11也引入了智能指针来管理动态对象.在新标准中,主要提供了shared_p ...
- 【C++11新特性】 C++11智能指针之weak_ptr
如题,我们今天要讲的是C++11引入的三种智能指针中的最后一个:weak_ptr.在学习weak_ptr之前最好对shared_ptr有所了解.如果你还不知道shared_ptr是何物,可以看看我的另 ...
- [CareerCup] 13.8 Smart Pointer 智能指针
13.8 Write a smart pointer class. A smart pointer is a data type, usually implemented with templates ...
- C++ smart pointer智能指针
在C++中,程序员可以直接操作内存,给编程增加了不少的灵活性.但是灵活性是有代价的,程序员必须负责自己负责释放自己申请的内存,否则就会出现内存泄露.智能指针就是为了解决这个问题而存在的.它和其他指 ...
- Smart pointer 智能指针小总结
Smart pointer line 58之后smart pointer里的计数已经是0,所以会真正释放它引用的对象,调用被引用对象的析构函数.如果继续用指针访问,会出现如下图的内存访问异常.所以说如 ...
- Smart Pointer 智能指针
P76 参考:http://www.cnblogs.com/lanxuezaipiao/p/4132096.html http://blog.csdn.net/hackbuteer1/article/ ...
- [C#]6.0新特性浅谈
原文:[C#]6.0新特性浅谈 C#6.0出来也有很长一段时间了,虽然新的特性和语法趋于稳定,但是对于大多数程序猿来说,想在工作中用上C#6.0估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...
随机推荐
- JBOOT使用总结
@Override public SwAdmin findById(long id) { return DAO.findFirst("SELECT * FROM sw_admin WHERE ...
- AS shortcuts
stl => statelessstf => statefulalt+enter, select element => add pading or somethingselect c ...
- 突然用xcode老版本调试老代码测试新机,报错"Could not find Developer Disk Image"回忆下
转载:https://www.cnblogs.com/blogwithstudyofwyn/p/6003176.html 说明:更新了手机的到了iOS 10.0.2.真机调试时候提示"Cou ...
- 木马防杀 花指令 OllyDbg
打开木马 入口地址 添加花指令 全0的地方,可以插入花指令 保存为可执行文件 随便选择几行,右击 保存文件
- jquery.widget开发(1)
jquery.widget是挂件,通过挂件模式挂载在jquery对象上,其实本质上也就是用了$.fn.extend和$.extend的扩展. http://blog.sina.com.cn/s/blo ...
- 【Intellij Idea】Intellij Idea 某个提示功能disable,想恢复怎么做
比如,恢复实现抽象类和接口的功能, 打开idea设置-->editor -->interntions 搜索 implement,然后将空白的打上勾
- NAT实验
实验内容 实验拓扑 实验编址 实验步骤1.基础配置根据编址表配置,检测ping 2.配置静态NAT在公司网关路由器R1上配置访问外网的默认路由 由于内网使用的都是私有IP地址,员工无法直接访问公网 ...
- 万众期待的kintone开发账号免费开放申请啦!
亲爱的小伙伴们,等了很久很久的kintone开发账号终于可以免费申请使用了! 有人想问了,什么是kintone? kintone是指无需开发知识,即可根据公司业务轻松创建系统的Cybozu的云服务. ...
- SQLAlchemy的应用创建
1.首先创建app文件夹 同django 创建app 一样 创建文件 在创建的views中写入两个蓝图函数为了操作数据库的增删改查 acc.py from flask import Blueprint ...
- Python爬虫爬企查查数据
因为制作B2b网站需要,需要入库企业信息数据.所以目光锁定企查查数据,废话不多说,开干! #-*- coding-8 -*- import requests import lxml import sy ...