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估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...
随机推荐
- 利用HashMap计算一个字符串中每个字符出现的次数
问题描述:计算一个字符串中每个字符出现的次数 问题分析:每个字符串对应着它的次数,且字符串唯一不重复,这让我们想到了HashMap中的键值对. 1.使用Scanner获取字符串 2.遍历字符串,获取每 ...
- nginx+rsync实现本地yum源以及公网yum源
1.配置nginx的autoindex模块,开启目录浏览功能 2.使用rsync同步公网源上的软件包,至本地目录中 3.配置客户端指向即可 1.nginx提供目录浏览功能 [root@xuliangw ...
- 【转载】 C#中decimal.TryParse方法和decimal.Parse方法的异同之处
在C#编程过程中,decimal.TryParse方法和decimal.Parse方法都可以将字符串string转换为decimal类型,但两者还是有区别,最重要的区别在于decimal.TryPar ...
- jquery实现倒计时
<html> <head> <meta charset="utf-8"/> <title>jquery实现倒计时</title ...
- Java实现在线预览--openOffice实现
简介 之前有写了poi实现在线预览的文章,里面也说到了使用openOffice也可以做到,这里就详细介绍一下. 我的实现逻辑有两种: 一.利用jodconverter(基于OpenOffice服务)将 ...
- 升级openssh漏洞
升级openssl和openssh 最近接收到客户的漏洞提醒,openssl和openssh的漏洞,解决办法就只有升级. 升级前环境 ~]# ssh -V OpenSSH_5.3p1, OpenSSL ...
- 【Flask】 python学习第一章 - 4.0 钩子函数和装饰器路由实现 session-cookie 请求上下文
钩子函数和装饰器路由实现 before_request 每次请求都会触发 before_first_requrest 第一次请求前触发 after_request 请求后触发 并返回参数 tear ...
- 22.centos7基础学习与积累-008-系统调优及安全设置
从头开始积累centos7系统运用 大牛博客:https://blog.51cto.com/yangrong/p5 1.关闭selinux功能: SELinux(Securety-EnhancedLi ...
- ES6--不定参数
<一>,在讨论ES6的不定参数之前,我们先一起回顾一下ECMAScript5的无名参数. 早先,javascript提供arguments对象检查函数的所有参数,从而不必定义每一个要用的参 ...
- 决策树算法原理--good blog
转载于:http://www.cnblogs.com/pinard/p/6050306.html (楼主总结的很好,就拿来主义了,不顾以后还是多像楼主学习) 决策树算法在机器学习中算是很经典的一个算法 ...