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>的更多相关文章

  1. C++2.0新特性(八)——<Smart Pointer(智能指针)之unique_ptr>

    一.概念介绍 unique_ptr它是一种在异常发生时可帮助避免资源泄露的smart pointer,实现了独占式拥有的概念,意味着它可确保一个对象和其他相应资源在同一时间只被一个pointer拥有, ...

  2. C++2.0新特性(七)——<Smart Pointer(智能指针)之weak_ptr>

    一.weak_ptr出现的意义 上一节提到过shared_ptr,它会自动释放“不再需要使用的对象”的相应的资源,但是它不是万能的,在某些时候(比如说循环引用),它会显得力不从心,这就是weak_pt ...

  3. 【C++11新特性】 C++11智能指针之shared_ptr

    C++中的智能指针首先出现在“准”标准库boost中.随着使用的人越来越多,为了让开发人员更方便.更安全的使用动态内存,C++11也引入了智能指针来管理动态对象.在新标准中,主要提供了shared_p ...

  4. 【C++11新特性】 C++11智能指针之weak_ptr

    如题,我们今天要讲的是C++11引入的三种智能指针中的最后一个:weak_ptr.在学习weak_ptr之前最好对shared_ptr有所了解.如果你还不知道shared_ptr是何物,可以看看我的另 ...

  5. [CareerCup] 13.8 Smart Pointer 智能指针

    13.8 Write a smart pointer class. A smart pointer is a data type, usually implemented with templates ...

  6. C++ smart pointer智能指针

      在C++中,程序员可以直接操作内存,给编程增加了不少的灵活性.但是灵活性是有代价的,程序员必须负责自己负责释放自己申请的内存,否则就会出现内存泄露.智能指针就是为了解决这个问题而存在的.它和其他指 ...

  7. Smart pointer 智能指针小总结

    Smart pointer line 58之后smart pointer里的计数已经是0,所以会真正释放它引用的对象,调用被引用对象的析构函数.如果继续用指针访问,会出现如下图的内存访问异常.所以说如 ...

  8. Smart Pointer 智能指针

    P76 参考:http://www.cnblogs.com/lanxuezaipiao/p/4132096.html http://blog.csdn.net/hackbuteer1/article/ ...

  9. [C#]6.0新特性浅谈

    原文:[C#]6.0新特性浅谈 C#6.0出来也有很长一段时间了,虽然新的特性和语法趋于稳定,但是对于大多数程序猿来说,想在工作中用上C#6.0估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...

随机推荐

  1. MVC利用JQuery异步加载PartialView

    Javascript: $("#indexList").load('/Test/Index',{"id":"1","name&qu ...

  2. 2019 盛趣游戏java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.盛趣游戏等公司offer,岗位是Java后端开发,因为发展原因最终选择去了盛趣游戏,入职一年时间了,也成为了面 ...

  3. workermanPHP聊天框架项目windows环境部署实践

    一.官方下载地址: https://www.workerman.net/workerman-chat 二.下载后解压至任意目录,如下图: 三.windows需配置PHP环境变量,如下图: 四.双击st ...

  4. MapReduce1.x与MapReduce2.x差异

    一.MapReduce1.x简介 1.图解 2.JobTracker 主节点,单点,负责调度所有的作用和监控整个集群的资源负载. 3.TaskTracker 从节点,自身节点资源管理和JobTrack ...

  5. React: 无状态组件生成真实DOM结点

    在上一篇文章中,我们总结并模拟了 JSX 生成真实 DOM 结点的过程,今天接着来介绍一下无状态组件的生成过程. 先以下面一段简单的代码举例: const Greeting = function ({ ...

  6. MySQL MHA工作原理

    MHA工作组件 MHA(Master High Availability)是一种MySQL高可用解决方案,由日本DeNA公司开发,主要用于在故障切换和主从提升时进行快速切换,并最大程度保证数据一致性. ...

  7. nginx-location语法匹配优先级

  8. selenium与webdriver驱动与firefox、 chrome匹配版本

    一.Chrome python3 selenium3.11.0(直接pip安装即可) chromedriver_win32:2.38 Chrome版本: 65.0.3325.146(正式版本)(32 ...

  9. swagger2 注解说明

    整体说明 用于controller类上 注解 说明 @Api 协议集描述 方法上 注解 说明 @ApiOperation - @ApiImplicitParams 方法上 @ApiImplicitPa ...

  10. sql中如何获取一条数据中所有字段的名称和值

    declare ) ) --获取表的列名 ,),filename INTO #templist FROM (select cl.name as filename from sys.tables AS ...