首先,如果你不知道什么是智能指针,请先移步:C++智能指针简单剖析

1.auto_ptr

 #ifndef AUTO_PTR_H
#define AUTO_PTR_H template<typename T>
class auto_ptr
{
public :
//使用explicit关键字避免隐式转换
explicit auto_ptr(T* p=);
~auto_ptr(); //使用另一个类型兼容的auto_ptr来初始化一个新的auto_ptr
template<typename U>
auto_ptr(auto_ptr<U>& rhs); template<typename U>
auto_ptr<T>& operator=(auto_ptr<U>& rhs); T& operator*() const;
T* operator->() const; //返回原始对象的指针
T* get() const;
//放弃指针的所有权
T* release();
//删除原有指针并获得指针p的所有权
void reset(T* p=); private:
T* pointee;
}; template<typename T>
auto_ptr<T>::auto_ptr(T* p)
:pointee(p)
{} template<typename T>
auto_ptr<T>::~auto_ptr()
{
delete pointee; //如果所有权被转移了,我们会将指针置0,delete空指针不会发生任何事
} template<typename T>
template<typename U>
auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
:pointee(rhs.release()) //转交所有权,即rhs将所有权转交给this,并将自身指针置0
{} template<typename T>
template<typename U>
auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
{
if(this!=&rhs)
reset(rhs.release());
return *this;
} template<typename T>
T& auto_ptr<T>::operator*() const
{
return *pointee;
} template<typename T>
T* auto_ptr<T>::operator->() const
{
return pointee;
} template<typename T>
T* auto_ptr<T>::get() const
{
return pointee;
} template<typename T>
T* auto_ptr<T>::release()
{
T* oldpointee=pointee;
pointee=; //置NULL
return oldpointee; //交出所有权
} template<typename T>
void auto_ptr<T>::reset(T* p)
{
if(pointee!=p)
{
delete pointee; //删除原有的
pointee=p; //设置新的
}
} #endif
 

2.shared_ptr

实现原理:

当多个shared_ptr管理同一个指针,仅当最后一个shared_ptr析构时,指针才被delete。为实现这一点,我们需要一个引用计数(reference counting)。引用计数指的是,所有管理同一个裸指针(raw pointer)的shared_ptr,都共享一个引用计数器,每当一个shared_ptr被赋值(或拷贝构造)给其它shared_ptr时,这个共享的引用计数器就加1,当一个shared_ptr析构或者被用于管理其它裸指针时,这个引用计数器就减1,如果此时发现引用计数器为0,那么说明它是管理这个指针的最后一个shared_ptr了,于是我们释放指针指向的资源。

在底层实现中,这个引用计数器保存在某个内部类型里(这个类型中还包含了deleter,它控制了指针的释放策略,默认情况下就是普通的delete操作),而这个内部类型对象在shared_ptr第一次构造时以指针的形式保存在shared_ptr中。shared_ptr在赋值和拷贝构造另一个shared_ptr时,这个指针被另一个shared_ptr共享。在引用计数归零时,这个内部类型指针与shared_ptr管理的资源一起被释放。此外,为了保证线程安全性,引用计数器的加1,减1操作都是原子操作,它保证shared_ptr由多个线程共享时不会出问题。

下面看看一个例子:

shared_ptr 是引用计数型(reference counting)智能指针,它在堆(heap)上放了个计数值(count)。shared_ptr 包含两个成员,一个是指向 Foo 的指针 ptr,另一个是 ref_count 指针(不一定是原始指针,有可能是 class 类型),指向堆上的 ref_count 对象。ref_count 对象有多个成员,具体的数据结构如图所示,其中 use_count为我们所说的计数,deleter 和 allocator 是可选的。

shared_ptr安全级别:

  • 一个 shared_ptr 对象实体可被多个线程同时读取;

  • 两个 shared_ptr 对象实体可以被两个线程同时写入,“析构”算写操作;

  • 如果要从多个线程读写同一个 shared_ptr 对象,那么需要加锁。

具体的代码实现这里不涉及,有兴趣的朋友可以去看一看boost的实现~

C++ 智能指针 auto_ptr 和 shared_ptr的更多相关文章

  1. C++智能指针 auto_ptr、shared_ptr、weak_ptr和unique_ptr

    手写代码是理解C++的最好办法,以几个例子说明C++四个智能指针的用法,转载请注明出处. 一.auto_ptr auto_ptr这是C++98标准下的智能指针,现在常常已经被C++标准的其他智能指针取 ...

  2. 聊聊智能指针 auto_ptr、shared_ptr、weak_ptr和unique_ptr

    本文为转载:https://www.cnblogs.com/zeppelin5/p/10083597.html,对作者有些地方做了修正. 手写代码是理解C++的最好办法,以几个例子说明C++四个智能指 ...

  3. 初次窥见智能指针auto_ptr和shared_ptr

    #include <memory>//shared_ptr要用的头文件 using namespace std; class A //测试auto_ptr和shared_ptr的delet ...

  4. 关于智能指针auto_ptr

    智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个 感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解. 本篇主要介绍auto_ptr 其 ...

  5. 智能指针auto_ptr & shared_ptr

    转载:智能指针auto_ptr 很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它.这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生 ...

  6. C++智能指针(auto_ptr)详解

    智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...

  7. 自己动手实现智能指针auto_ptr

    面试的时候,我们经常会被问到如何自己动手实现智能指针auto_ptr.今天我就一边参考STL库中的源代码,一边将auto_ptr的实现敲一遍. auto_ptr归根到底是一个模版类,那么这个类要实现哪 ...

  8. C++ 智能指针auto_ptr

    template<class T> class auto_ptr { public: ); // Item M5 有“explicitfor”// 的描述 template<clas ...

  9. C++中的智能指针(auto_ptr)

    实际上auto_ptr 仅仅是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势.使用它不必每次都手动调用delete去释放内存.当然有利也有弊,也不是全然完美的. 本 ...

随机推荐

  1. nyoj 擅长排列的小名II

    擅长排列的小明 II 时间限制:1000 ms  |           内存限制:65535 KB 难度:3   描述 小明十分聪明,而且十分擅长排列计算. 有一天小明心血来潮想考考你,他给了你一个 ...

  2. jsp文件调用本地文件的方法(Tomcat server.xml 设置虚拟目录)

    JSP文件: <video id="my-video" class="video-js" controls preload="auto" ...

  3. Python基础学习篇章三

    一. Python对象类型 1. 对象是Python最基本的概念,一个Python程序可以分解为模块.语句.表达式.和对象.它们的关系如下:(1)程序由模块构成 (2)模块包含语句 (3)语句包含表达 ...

  4. api-gateway实践(13)新服务网关 - 断路保护/熔断机制

    参考链接:SpringCloud的Hystrix(五) Hystrix机制 新需求列表 1.在线测试 根据定义,生成输入界面, 点击测试, 验证参数,发起调用,返回执行结果 2.熔断保护 两个实现类: ...

  5. 云计算(2)it 是什么

    2015年,全世界在it上面的花费达到3亿8千亿美金之多. 云数据中心:核心基础架构,云计算的物理载体,提供数据处理.存储和高性能计算支撑,包括服务器.存储.冷却.机房空间和能耗管理等. 超大规模的云 ...

  6. Spark入门(1-5)Spark统一了TableView和GraphView

    下面我们看一下图计算的简单示例: 从图我们可以看出, 拿到Wikipedia的文档后,我们可以: 1.Wikipedia的文档 -- > table视图 -- >分析Hyperlinks超 ...

  7. Python之编码

    一.Python2与Python3的区别 1.从宏观上考虑,Python2重复代码太多,错误率高,不够规范.Python崇尚的是语言简洁.优美.清晰.Python3更加规范,重复代码少: 2.Pyth ...

  8. 通过wget工具下载指定文件中的URLs对应的资源并保存到指定的本地目录中去并进行文件完整性与可靠性校验

    创建URLs文件在终端输入cd target_directory回车,便把当前文件夹切换到了目标文件夹target_directory,此后创建的文件都会丢它里面在终端输入cat > URLs回 ...

  9. Mysql 5.1的坑

    1.数据库表是区分大小写的 之前程序在5.7数据库没问题,测试环境上数据库是5.1的,就提示表找不到. 2.同样的sql,在5.1上会提示事务获取锁失败,超时返回.而5.7上正常.原因暂未找到.

  10. python基础(初识Python)

    python基础(初识Python) 本章内容: Python 的种类 Python 的环境 Python 入门(解释器.编码.pyc文件.脚步传入参数.变量.输入.流程控制与缩进.while循环) ...