C++ 智能指针 auto_ptr 和 shared_ptr
首先,如果你不知道什么是智能指针,请先移步: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的更多相关文章
- C++智能指针 auto_ptr、shared_ptr、weak_ptr和unique_ptr
手写代码是理解C++的最好办法,以几个例子说明C++四个智能指针的用法,转载请注明出处. 一.auto_ptr auto_ptr这是C++98标准下的智能指针,现在常常已经被C++标准的其他智能指针取 ...
- 聊聊智能指针 auto_ptr、shared_ptr、weak_ptr和unique_ptr
本文为转载:https://www.cnblogs.com/zeppelin5/p/10083597.html,对作者有些地方做了修正. 手写代码是理解C++的最好办法,以几个例子说明C++四个智能指 ...
- 初次窥见智能指针auto_ptr和shared_ptr
#include <memory>//shared_ptr要用的头文件 using namespace std; class A //测试auto_ptr和shared_ptr的delet ...
- 关于智能指针auto_ptr
智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个 感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解. 本篇主要介绍auto_ptr 其 ...
- 智能指针auto_ptr & shared_ptr
转载:智能指针auto_ptr 很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它.这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生 ...
- C++智能指针(auto_ptr)详解
智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...
- 自己动手实现智能指针auto_ptr
面试的时候,我们经常会被问到如何自己动手实现智能指针auto_ptr.今天我就一边参考STL库中的源代码,一边将auto_ptr的实现敲一遍. auto_ptr归根到底是一个模版类,那么这个类要实现哪 ...
- C++ 智能指针auto_ptr
template<class T> class auto_ptr { public: ); // Item M5 有“explicitfor”// 的描述 template<clas ...
- C++中的智能指针(auto_ptr)
实际上auto_ptr 仅仅是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势.使用它不必每次都手动调用delete去释放内存.当然有利也有弊,也不是全然完美的. 本 ...
随机推荐
- NFC驱动调试
1.NFC基本概念: NFC 又称为近场通信,是一种新兴技术,可以在彼此靠近的情况下进行数据交换,是由非接触式射频识别(RFID) 及互连互通技术整合演变而来,通过单一芯片集成感应式读卡器: NFC有 ...
- 【编程开发】PHP---面向对象
面向对象编程 类:在现实世界中,任何事物都有种类的概念:车 类是由特征和行为构成的. 特征:都是不动的,从出厂的时候就已经内置好了(属性) 行为:一种动的状态.(方法(函数)) 行为依赖于这些特征,而 ...
- java的<<左移,>>右移,>>>无符号右移
>>右移 右移,道在二进制中,假设用一个32位的Int表示一个64,那么高位就都是0,所以当我们把整个二进制数右移,如0100000 >> 2 = 0001000,可以看到右移 ...
- jenkins 简单实现php集成上线部署
基于公司git版本控制,搭建jenkins实现php集成部署(没有用gitlab,测试服配置较低,gitlab卡的不要不要的了-) 一.安装jenkins相关依赖 wget -O /etc/yum.r ...
- XPath编写规则学习
XPath编写规则学习 辅助工具:firefox安装findbugs,view Xpath firefox :Xpath验证方式:$x("xpath"); 粘贴xpath语句回 ...
- OAuth2.0学习(1-7)授权方式4-客户端模式(Client Credentials Grant)
授权方式4-客户端模式(Client Credentials Grant) 客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提 ...
- 输入法searchLookUpEditd的使用
输入法是DevExpress系列控件比较常用的一个控件.searchLookUpEditd控件集成了快捷输入法,可以使用拼音,五笔等方式快捷输入. 先展示一下输入法的效果
- 彻底理解了call()方法,apply()方法和bind()方法
javascript中的每一个作用域中都有一个this对象,它代表的是调用函数的对象.在全局作用域中,this代表的是全局对象(在web浏览器中指的是window).如果包含this的函数是一个对象的 ...
- hdu4864 Task贪心好题
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4864 题目大意: 有n个机器,m个任务.每个机器至多能完成一个任务.对于每个机器,有一个最大运行时间 ...
- url的解码方式
#coding:utf-8 import urllib legal_person_string = "%E6%B3%95%E5%AE%9A%E4%BB%A3%E8%A1%A8%E4%BA%B ...