关于shared_ptr

首先了解shared_ptr毫无疑问的是智能指针的一种,智能指针是为了解决在大型代码里无法不好控制指针的问题,例如:在类里面如果出现了动态开辟出来的空间,有一个指针指向这块空间,如果在相应的作用范围之内没有将其delete掉会造成内存的泄漏,所以这样就必须手动的对这一块空间进行释放,但是这非常不利于我们的工作,所以我们就引入了智能指针,它是一个类,它的作用范围结束就自动释放了,所以这样达到了智能的管理这一块空间。所以shared_ptr也自然地拥有了上面的特性和功能,现在就对shared_ptr做一个较为深层次的理解并掌握它的使用。

Boost库的智能指针(ps:新的C++11标准中已经引入了unique_ptr/shared_ptr/weak_ptr),所以言下之意就是在使用unique_ptr/shared_ptr/weak_ptr之前都需要进行boost编译,所以这样也不方便使用,在c++11中将boost也纳入了标准,这样就可以在较高版本的编译器下直接使用这些智能指针。所以shared_ptr可以在我的编译器下直接使用而不需要编译,因为我的编译器是13版的。

SharedPtr,利用字符串相似的写时拷贝方式实现,让创建的对象维护同一块空间,并且用一个int* _pcount对引用这块空间的次数进行计数。

现在先对shared_ptr进行一个模拟的实现:

template <typename T>

class SharedPtr //相似于string类的写实拷贝,如果用深拷贝的方式达不到指针的效果,p1=p2,不能让p1和p2同时管理一块空间

{

public:

SharedPtr( T* ptr )

:_pcount( new int (1))

, _ptr( ptr)

{

}

~SharedPtr()

{

if (--(*_pcount) == 0)

{

delete _ptr;

delete _pcount;

}

}

SharedPtr( const SharedPtr & s)

:_ptr( s._ptr)

, _pcount( s._pcount)

{

++(*_pcount);

}

/* 这种写法较为复杂

SharedPtr& operator=(const SharedPtr& s)//分三种情况,自己给自己赋值,两对象指向同一空间,指向不同的空间

{

if (_ptr != s._ptr)

{

if (--(*_pcount) == 0)

{

delete _ptr;

delete _pcount;

}

_ptr = s._ptr;

_pcount = s._pcount;

++(*_pcount);

}

return *this;

}

*/

SharedPtr& operator=( const SharedPtr s )//这种写法较为简单,并且这样写法一致性好,在自赋值,指向同一块空间赋值,指向不同空间的赋值都满足

{

swap(_ptr, s._ptr);

swap(_pcount, s._pcount);

return *this ;

}

T& operator*()

{

return *_ptr;

}

T* operator->()

{

return _ptr;

}

protected:

T* _ptr;

int* _pcount;

};

上面是实现了shared_ptr的几个基本函数,shared_ptr无疑的要实现成模板类,因为它在运用时可以是不同类型的指针,同时它还要尽力的模仿的和原生指针比较相似。

/*****************************************************************/

上面是对shared_ptr的原理进行了分析,现在对shared_ptr在使用时要注意的问题进行分析(首先要了解shared_ptr在使用时会发生循环引用和定制删除器这两个要点)

  1. 循环引用问题

shared_ptr的循环引用问题及其解决方法:(形成循环引用的原因是因为cur最后释放会依赖于next->_prev的释放,而next的释放又依赖于cur->_next的释放,所以形成无法释放的局面)

weak_ptr不完全增加引用计数,打破shared_ptr的死穴

2.定制删除器:

定置删除器:在使用share_ptr时,因为shared_ptr只能管理用new开辟出来的空间,因为shared_ptr析构函数的实现是依靠delete _ptr实现,所以对于malloc和fopen等操作并不能做到析构,如果不定置删除器将会导致程序的崩溃,因为malloc需要用free来解决,fopen需要用fclose来解决(利用仿函数这个方法来实现定置删除器)利用仿函数来解决问题,仿函数是一个类,对象可以像一个函数一样调用,它是一个空类。

下面实现定制删除器的使用:

#include<iostream>

#include<memory>

using namespace std;

template <typename T,typename Del>

class SharedPtr

{

public:

void Release()

{

if (--(*_pcount) == 0)

{

_del(_ptr);

delete _pcount;

}

}

SharedPtr(T* ptr)

:_ptr(ptr)

, _pcount(new int(1))

{

}

~SharedPtr()

{

Release();

}

private:

T* _ptr;

int* _pcount;

Del _del;

};

template <typename T>//定制删除器(new)

struct Del//是个类,可以当作一个模板参数

{

void operator()(T* _ptr)

{

cout << "delete _ptr" << endl;

delete _ptr;

}

};

template <typename T>//定制删除器(malloc)

struct Free

{

void operator()(T* _ptr)//重载(),可以像函数一样使用这个类

{

cout << "Free _ptr" << endl;

free(_ptr);

}

};

template <typename T>//定制删除器(文件)

struct Fclose

{

void operator()(T* _ptr)

{

cout << "Fclose _ptr" << endl;

fclose(_ptr);

}

};

void testDel()

{

SharedPtr<int, Del<int>> sp1(new int(1));

SharedPtr<int, Free<int>> sp2((int*)malloc(sizeof(int)));

FILE* fp = fopen("yxt.txt", "r");

SharedPtr<FILE, Fclose<FILE>> sp3(fp);

}

int main()

{

testDel();

system("pause");

return 0;

}

时间: 2024-10-10 18:31:47

关于shared_ptr的相关文章

实现类似shared_ptr的引用计数

13.27 定义使用引用计数版本的HasPtr #include<iostream> #include<string> #include<new> using namespace std; class HasPtr { public: HasPtr(const string &s=string()):ps(new string(s)),i(0),use(new size_t(1)) {cout<<"constructer"<

智能指针tr1::shared_ptr、boost::shared_ptr使用

对于tr1::shared_ptr在安装vs同时会自带安装,但是版本较低的不存在.而boost作为tr1的实现品,包含 "Algorithms Broken Compiler Workarounds Concurrent Programming Containers Correctness and Testing Data Structures Domain Specific Function Objects and Higher-order Programming Generic Progra

C++ shared_ptr

晕晕乎乎,其他的再补充 1.shared_ptr 主要是为了方便管理内存而存在的,C++程序中不会再出现new 和 delete,内存的分配和析构全部由shared_ptr进行管理 2.当程序中对某个对象进行复制或者引用的时候,shared_ptr会有一个引用计数这个东西,每当使用一次就+1,用完之后-1,直到减为0的时候再将申请的内存(资源)释放掉

C++智能指针剖析(下)boost::shared_ptr&amp;其他

1. boost::shared_ptr 前面我已经讲解了两个比较简单的智能指针,它们都有各自的优缺点.由于 boost::scoped_ptr 独享所有权,当我们真真需要复制智能指针时,需求便满足不了了,如此我们再引入一个智能指针,专门用于处理复制,参数传递的情况,这便是如下的boost::shared_ptr. boost::shared_ptr 属于 boost 库,定义在 namespace boost 中,包含头文件#include<boost/smart_ptr.hpp> 便可以使

shared_ptr 和 unique_ptr

c++11标准废除乐auto_ptr, C++ 标准库智能指针 使用这些智能指针作为将指针封装为纯旧 C++ 对象 (POCO) 的首选项. unique_ptr 只允许基础指针的一个所有者. 除非你确信需要 shared_ptr,否则请将该指针用作 POCO 的默认选项. 可以移到新所有者,但不会复制或共享. 替换已弃用的auto_ptr. 与 boost::scoped_ptr 比较. unique_ptr 小巧高效:大小等同于一个指针且支持 rvalue 引用,从而可实现快速插入和对 ST

Boost库中shared_ptr(上)

1.共享性智能指针(shared_ptr) 引用计数型指针 shared_ptr是一个最像指针的"智能指针",是boost.smart_ptr库中最有价值,最重要,也是最有用的.  shared_ptr实现的是引用技术型的智能指针,可以被拷贝和赋值,在任意地方共享它,当没有代码使用(此时引用         计数为0)它才删除被动态分配的对象.shared_ptr也可以被安全的放到标准容器中: 2.怎么使用shared_ptr 举一个操作的例子: #include<iostrea

智能指针的模拟实现 auto_ptr scoped_ptr shared_ptr

RAII(Resource Acquisition Is Initialization) 资源分配即初始化,定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放. 智能指针:用自动化或者说智能的指针来实现对动态内存的释放.它是一个类,有类似指针的功能. 常见的智能指针:auto_ptr/scoped_ptr/scoped_array/shared_ptr/shared_array,由于scoped_array和scoped_

智能指针的模拟实现shared_ptr 循环引用 定置删除器

auto_ptr与scoped_ptr的实现见本人的上篇博客. 三.shared_ptr shared_ptr的实现原理是通过引用计数来实现,只有当引用计数为1时才释放空间,否则只需将引用计数减1.拷贝和赋值将引用计数加1,具体代码如下: template <typename T> class SharedPtr { public: SharedPtr(); SharedPtr(T* ptr); SharedPtr(const SharedPtr<T>& ap); ~Sha

智能指针 std::auto_ptr 和 shared_ptr

需要注意: auto_ptr 类可以用于管理由 new 分配的单个对象,但是无法管理动态分配的数组(我们通常不会使用数组,而是使用 vector 代替数组).auto_ptr 在拷贝和赋值的时候有不寻常的行为,因此 auto_ptrs 不能被保存在 stl 的容器中.当 auto_ptr 离开了自己的作用域或者被销毁,由 auto_ptr 管理的对象也会被销毁. 使用std::auto_ptr需要的头文件: #include <memory> // 示例 1(b): 安全代码, 使用了auto

智能指针——shared_ptr

boost::scoped_ptr虽然简单易用,但它不能共享所有权的特性却大大限制了其使用范围,而boost::shared_ptr可以解决这一局限.顾名思义,boost::shared_ptr是可以共享所有权的智能指针 boost::shared_ptr的管理机制其实并不复杂,就是对所管理的对象进行了引用计数,当新增一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数加一:减少一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数减一,如果该对