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. 2019 巨人网络java面试笔试题 (含面试题解析)

    本人3年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.巨人网络等公司offer,岗位是Java后端开发,最终选择去了巨人网络. 面试了很多家公司,感觉大部分公司考察的点 ...

  2. 最全的 pip 使用指南,50% 你可能没用过

    所有的 Python 开发者都清楚,Python 之所以如此受欢迎,能够在众多高级语言中,脱颖而出,除了语法简单,上手容易之外,更多还要归功于 Python 生态的完备,有数以万计的 Python 爱 ...

  3. win 修改notebook路径

    开始发现 notebook 默认的路径是 C:\Users\Administrator 需要修改 将目标中的%USERPROFILE% 直接删掉了

  4. Python进阶(二)----函数参数,作用域

    Python进阶(二)----函数参数,作用域 一丶形参角度:*args,动态位置传参,**kwargs,动态关键字传参 *args: ​ 动态位置参数. 在函数定义时, * 将实参角度的位置参数聚合 ...

  5. Matlab模板模式

    在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板.它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行.本文以数据库SQL语法为例来阐述模板模 ...

  6. GO实现Cron解析和定时任务

    Go的Cron表达式解析库:github.com/gorhill/cronexpr 核心类型和方法 // 表达式对象 expr *cronexpr.Expression // 解析cron表达式 ex ...

  7. python检测远程udp端口是否打开的代码

    研发过程,把开发过程较好的代码收藏起来,如下的代码内容是关于python检测远程udp端口是否打开的代码,希望对各朋友有较大帮助. import socketimport threadingimpor ...

  8. Spring的核心机制:依赖注入

    依赖注入的概念 当一个对象要调用另一个对象时,一般是new一个被调用的对象,示例: class  A{ private B b=new B(); public  void  test(){ b.say ...

  9. 设置Linux 程序lib搜索目录

    设置Linux 程序lib搜索目录:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:lib路径,例如: export LD_LIBRARY_PATH=$LD_LIBRA ...

  10. 数据库开发-Django ORM的多对多查询

    数据库开发-Django ORM的多对多查询 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.联合主键问题 CREATE TABLE `employees` ( `emp_no` ...