【C++】智能指针shared_ptr 定位删除器(仿函数)

智能指针shared_ptr 用引用计数实现看起来不错,但却存在问题。

1、引用计数更新存在着线程安全;

2、循环引用--使用一个弱引用智能指针(weak_ptr)来打破循环引用(weak_ptr不增加引用计数)

3、定置删除器和空间分配器

比如打开一个文件的关闭,用malloc开辟出来的空间,用引用计数实现会出现问题。

对改变引用计数时加锁可以解决引用计数更新存在着线程安全。

循环引用问题

#include<iostream>
using namespace std;
#include<memory>//库中包含shared_ptr
struct ListNode
{
	shared_ptr<ListNode> _prev;
	shared_ptr<ListNode> _next;
	~ListNode()
	{
		cout << "~ListNode()" << endl;
	}
};

void  Test2()
{
	shared_ptr<ListNode> cur(new ListNode);//1
	shared_ptr<ListNode> next(new ListNode);//2
	cout << "cur->" << cur.use_count() << endl;//use_count返回shared_ptr的引用计数
	cout << "next->" << next.use_count() << endl;

	cur->_next = next;//3
	next->_prev = cur;//4
	cout << "cur->" << cur.use_count() << endl;
	cout << "next->" << next.use_count() << endl;
}
//经过语句1、2之后cur和next的引用计数为1,经过语句1、2后引用计数为2。
//但是最后两个对象均不能释放,因为cur的要释放的前提是next释放,而next的释放又依赖于cur的释放,最后就形成了循环引用。
//weak_ptr(弱引用智能指针)会对引用计数会做特殊处理解决这个问题。
struct ListNode
{
    weak_ptr<ListNode> _prev;
    weak_ptr<ListNode> _next;
    ~ListNode()
    {
        cout << "~ListNode()" << endl;
    }
};

定置删除器和空间分配器(ps:空间分配器的定置特殊场景下才会这样使用)

如果指针是一个指向文件类型的,在析构函数中只需关闭文件即可,而不是释放空间;如果空间是通过malloc开辟出来的,那么在析构函数中要调用free函数,而不是delete操作符。上述问题通过仿函数就可以解决。具体代码如下:

template<class T>
class Del
{
public:
	void operator() (const T *ptr)
	{
		delete ptr;
	}
};
//仿函数实现FClose和Free
struct FClose
{
	void operator() (void* ptr)
	{
		cout << "Close" << endl;
		fclose((FILE*)ptr);
	}
};
struct Free
{
	void operator() (void* ptr)
	{
		cout << "Free" << endl;
		free(ptr);
	}
};

template<class T,class Deleter=Del<T>>
class SharedPtr
{
public:
	SharedPtr(T* ptr)
		:_ptr(ptr)
		, _pCount(new long(1))
	{}
	SharedPtr(T* ptr,Deleter del)
		:_ptr(ptr)
		, _pCount(new long(1))
		, _del(del)
	{}
	SharedPtr<T>& operator=(SharedPtr<T> sp)
	{
		swap(_ptr, sp._ptr);
		swap(_pCount, sp._pCount);
		return *this;
	}
	~SharedPtr()
	{
		cout << "~SharedPtr()" << endl;
		Release();
	}
	T& operator*()
	{
		return *_ptr;
	}
	T* GetPtr()//返回原指针_ptr
	{
		return  _ptr;
	}
	T* operator->()
	{
		return _ptr;
	}
	void Release()//释放内存
	{
		if (--(*_pCount) == 0)
		{
			_del(_ptr);
			delete _pCount;
		}
	}
private:
	T* _ptr;
	long* _pCount;
	Deleter _del;
};

void Test3()
{
	//定制删除器和分配器
	SharedPtr<int> sp(new int(6));
	SharedPtr<FILE, FClose> sp1(fopen("test.text", "w"), FClose());
	SharedPtr<int, Free> sp2((int*)malloc(sizeof(int)* 6), Free());
}
时间: 2024-10-24 15:06:37

【C++】智能指针shared_ptr 定位删除器(仿函数)的相关文章

C++智能指针 shared_ptr

C++智能指针 shared_ptr shared_ptr 是一个标准的共享所有权的智能指针, 允许多个指针指向同一个对象. 定义在 memory 文件中(非memory.h), 命名空间为 std. shared_ptr 是为了解决 auto_ptr 在对象所有权上的局限性(auto_ptr 是独占的), 在使用引用计数的机制上提供了可以共享所有权的智能指针, 当然这需要额外的开销: (1) shared_ptr 对象除了包括一个所拥有对象的指针外, 还必须包括一个引用计数代理对象的指针. (

智能指针 shared_ptr 解析

最近正在进行<Effective C++>的第二遍阅读,书里面多个条款涉及到了shared_ptr智能指针,介绍的太分散,学习起来麻烦,写篇blog整理一下. LinJM   @HQU shared_ptr是一个智能指针.在C++ 11颁布之前,它包含在TR1(Technical Report 1)当中,现在囊括在C++11的标准库中. 智能指针 智能指针(Smart pointers)是存储"指向动态分配(在堆上)的对象的指针"的对象.也就是说,智能指针其实是个对象.不过

C/C++之智能指针shared_ptr

1.定义 shared_ptr的作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象.这便是所谓的引用计数(reference counting).一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除.这在非环形数据结构中防止资源泄露很有帮助. auto_ptr由于它的破坏性复制语义,无法满足标准容器对元素的要求,因而不能放在标准容器中:如果我们希望当容器析构时能自动把它容纳的指针元素所指的对象删除时,通常采用一些间接的方式来实现,显得比较繁琐

c/c++ 智能指针 shared_ptr 使用

智能指针 shared_ptr 使用 上一篇智能指针是啥玩意,介绍了什么是智能指针. 这一篇简单说说如何使用智能指针. 一,智能指针分3类:今天只唠唠shared_ptr shared_ptr unique_ptr weak_ptr 二,下表是shared_ptr和unique_ptr都支持的操作 操作 功能描述 shared_ptr<T> sp 空智能指针,可以指向类型为T的对象 unique_ptr<T> up 空智能指针,可以指向类型为T的对象 p 将p用作一个条件判断,如果

深入剖析智能指针 shared_ptr

在effective C++经常会提到智能指针,这里对shared_ptr进行一个总结: 1 简要介绍用法 智能指针主要是用于资源管理,当申请一个资源的时候为了保证在离开控制流的时候对应资源应该得到相应的释放,这个时候如果资源对应一个类,在构造类的时候进行资源的分配(也就是书中经常提到的Resource Acquisition  Is Initialization RAII),在对象离开作用域的时候调用对应的析构函数资源得到适当的释放 这里有几个智能指针得到应用: auto_ptr: 被销毁的时

C++ 智能指针 shared_ptr 分析

引文: C++对指针的管理提供了两种解决问题的思路: 1.不允许多个对象管理一个指针 2.允许多个对象管理一个指针,但仅当管理这个指针的最后一个对象析构时才调用delete ps:这两种思路的共同点就是只允许delete一次,下面将讨论的shared_ptr就是采用思路1实现的 ps:智能指针不是指针,而是类,可以实例化为一个对象,来管理裸指针 1.shared_ptr的实现原理: shared_ptr最本质的功能:"当多个shared_ptr管理同一个指针,仅当最后一个shared_ptr析构

Boost库中的智能指针 shared_ptr智能指针

shared_ptr智能指针的意思即:boost::shared_ptr是可以智能的管理动态分配的内存资源,几个智能指针可以同时共享一个动态分配的内存的所有权. 下面我们通过一个例子来学习一下它的用法: 注 :使用shared_ptr智能指针,要加入#include <boost/shared_ptr.hpp>头文件 class example { public: ~example() { std::cout <<"It's over\n"; } void do

Boost智能指针——shared_ptr

转: http://www.cnblogs.com/TianFang/archive/2008/09/19/1294521.html boost::scoped_ptr虽然简单易用,但它不能共享所有权的特性却大大限制了其使用范围,而boost::shared_ptr可以解决这一局限.顾名思义,boost::shared_ptr是可以共享所有权的智能指针,首先让我们通过一个例子看看它的基本用法: #include <string> #include <iostream> #inclu

shared_ptr(下) 删除器

1.shared_ptr中的px出现原因 方便对其数据空间的管理,取值和获取地址将极大的方便我们的操作. 2.解决析构函数 避免内存空间的泄漏.new出来的空间都没有释放掉! 释放拥有权靠的是引用计数. ~shared_count(){      if(pi){  //判断所指父类是否为空         pi->release(); //释放new出来的对象和外部new出来的空间     } } /////////////////////////////////////////////////