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

RAII(Resource Acquisition Is Initialization)

资源分配即初始化,定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放。

智能指针:用自动化或者说智能的指针来实现对动态内存的释放。它是一个类,有类似指针的功能。

常见的智能指针:auto_ptr/scoped_ptr/scoped_array/shared_ptr/shared_array,由于scoped_array和scoped_ptr比较类似,shared_array和shared_ptr又比较类似,所以我们只实现auto_ptr/scoped_ptr/shared_ptr。

一、auto_ptr

最开始auto_ptr的成员变量主要有T* _ptr,bool _owner,主要实现原理是在构造对象时赋予其管理空间的所有权,在析构函数中通过_owner的真否来释放所有权,并且在拷贝或赋值后通过将_owner设为false,转移空间的所有权。具体实现代码如下:

template <typename T>
class AutoPtr
{
public:
	AutoPtr(T* ptr = NULL);
	AutoPtr(AutoPtr<T>& ap);
	AutoPtr<T>& operator=(AutoPtr<T>& ap);
	~AutoPtr();
	T& operator*()const;
	T* operator->()const;
	T* GetStr()const;
protected:
	T* _ptr;
	bool _owner;
};

template <typename T>
AutoPtr<T>::AutoPtr(T* ptr) : _ptr(ptr), _owner(true)
{}

template <typename T>
AutoPtr<T>::AutoPtr(AutoPtr<T>& ap) : _ptr(ap._ptr), _owner(true)
{
	ap._owner = false;
}

template <typename T>
AutoPtr<T>& AutoPtr<T>::operator=(AutoPtr<T>& ap)
{
	if (this != &ap)
	{
		delete this->_ptr;
		this->_ptr = ap._ptr;
		this->_owner = true;
		ap._owner = false;
	}
	return *this;
}

template <typename T>
AutoPtr<T>::~AutoPtr()
{
	if (this->_ptr)
	{
		this->_owner = false;
		delete this->_ptr;
	}
}

template <typename T>
T& AutoPtr<T>::operator*()const
{
	return *(this->_ptr);
}

template <typename T>
T* AutoPtr<T>::operator->()const
{
	return this->_ptr;
}

template <typename T>
T* AutoPtr<T>::GetStr()const
{
	return (this->_ptr);
}

主要问题:如果拷贝出来的对象比原来的对象出作用域,则原来的对象的_owner虽然为false,但却课访问一块已经释放的一块空间。

auto_ptr的第二种实现方法:还是管理空间的所有权转移,但这种实现方法中没有_owner。构造和析构和上述实现方法类似,但拷贝和赋值后直接将_ptr赋为空,禁止其在访问原来的内存空间。具体代码如下:

template <typename T>
class AutoPtr
{
public:
	AutoPtr();
	AutoPtr(T* ptr);
	AutoPtr(AutoPtr<T>& ap);
	AutoPtr<T>& operator=(AutoPtr<T>& ap);
	~AutoPtr();
	T& operator*()const; 
	T* operator->()const;
	T* GetStr()const;
protected:
	T* _ptr;
};

template <typename T>
AutoPtr<T>::AutoPtr() : _ptr(NULL)
{}

template <typename T>
AutoPtr<T>::AutoPtr(T* ptr) : _ptr(ptr)//不能写成const T* ptr,因为否则为const类型的赋值给非const类型
{}

template <typename T>
AutoPtr<T>::AutoPtr(AutoPtr<T>& ap) : _ptr(ap._ptr)
{
	ap._ptr = NULL;
}

template <typename T>
AutoPtr<T>& AutoPtr<T>::operator=(AutoPtr<T>& ap)
{
	if (this != &ap)
	{
		delete this->_ptr;
		this->_ptr = ap._ptr;
		ap._ptr = NULL;
	}
	return *this;
}

template <typename T>
AutoPtr<T>::~AutoPtr()
{
	if (this->_ptr)
	{
		delete this->_ptr;
	}
}

template <typename T>
T& AutoPtr<T>::operator*()const
{
	return *(this->_ptr);
}

template <typename T>
T* AutoPtr<T>::operator->()const
{
	return this->_ptr;
}

template <typename T>
T* AutoPtr<T>::GetStr()const
{
	return (this->_ptr);
}

二、scoped_ptr

scoped_ptr的实现原理是防止对象的拷贝与赋值。具体实现是将拷贝构造函数和赋值运算符重载函数设置为保护或私有,并且只声明不实现,设置为保护或私有是防止他人在类外自己实现。具体代码如下:

template <typename T>
class ScopedPtr
{
public:
	ScopedPtr(T* ptr = NULL);
	~ScopedPtr();
	T* operator->()const;
	T& operator*()const;
	T* GetPtr()const;
protected:
	ScopedPtr(const ScopedPtr<T>& ptr);
	ScopedPtr<T>& operator=(const ScopedPtr<T>& ptr);
protected:
	T* _ptr;
};

template <typename T>
ScopedPtr<T>::ScopedPtr(T* ptr) :_ptr(ptr)
{}

template <typename T>
ScopedPtr<T>::~ScopedPtr()
{
	if (this->_ptr)
	{
		delete this->_ptr;
	}
}

template <typename T>//应用于类型为结构体时
T* ScopedPtr<T>::operator->()const
{
	return this->_ptr;
}

template <typename T>
T& ScopedPtr<T>::operator*()const
{
	return *(this->_ptr);
}

template <typename T>
T* ScopedPtr<T>::GetPtr()const
{
	return (this->_ptr);
}

shared_ptr的实现及相关问题见下篇博客。

时间: 2024-07-30 13:38:47

智能指针的模拟实现 auto_ptr scoped_ptr shared_ptr的相关文章

智能指针:模拟实现auto_ptr,scoped_ptr,shared_ptr

RAII(Resource Acquisition Is Initialization) 资源分配即初始化,定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放. 所谓智能指针就是智能/自动化的管理指针所指向的动态资源的释放. STL--auto_ptr Boost库的智能指针(ps:新的C++11标准中已经引入了unique_ptr/shared_ptr/weak_ptr) 常见的智能指针有:auto_ptr/scoped

智能指针(模拟实现auto_ptr,shared_ptr,scooeptr 以及定制删除器c++ 实现)

#define  _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; template<class T> class Auto_ptr { public:  Auto_ptr(T* _x) :x(_x)  {}  Auto_ptr(Auto_ptr<T> &s) :x(s.x)  {   s.x = NULL;  }  Auto_ptr& operator=(Auto_ptr&l

C++ Primer 学习笔记_56_STL剖析(十一)(原boost库):详解智能指针(unique_ptr(原scoped_ptr) 、shared_ptr 、weak_ptr源码分析)

注意:现在boot库已经归入STL库,用法基本上还和boost类似 在C++11中,引入了智能指针.主要有:unique_ptr, shared_ptr, weak_ptr. 这3种指针组件就是采用了boost里的智能指针方案.很多有用过boost智能指针的朋友,很容易地就能发现它们之间的关间: std boost 功能说明 unique_ptr scoped_ptr 独占指针对象,并保证指针所指对象生命周期与其一致 shared_ptr shared_ptr 可共享指针对象,可以赋值给shar

智能指针的模拟实现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

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> 便可以使

智能指针(模拟实现AutoPtr、ScopedPtr、SharedPtr)

模拟实现AutoPtr.ScopedPtr.SharedPtr 智能指针实际上就是能够智能化的管理动态开辟空间的内存释放问题,C++中引入智能指针,很大一方面是当我们在动态开辟空间时,由于一些疏忽,或者说是对于一些代码,执行的顺序不是我们预期能够想到的,导致一些内存泄露的问题,使得程序健壮性不够,可维护性降低. 智能指针的基本特点: 1)智能指针管理的是一块内存的释放. 2)智能指针是一个类,有类似指针的功能. 下面主要是AutoPtr的理解: 当我们了解上面的知识后,模拟实现智能指针AutoP

智能指针(smart pointer)(1):auto_ptr

智能指针解决了资源生存期管理的问题(尤其是动态分配的对象).智能指针有各种不同的风格.多数都有一种共同的关键特性:自动资源管理.这种特性可能以不同的方式出现:如动态分配对象的生存期控制,和获取及释放资源 (文件, 网络连接).这里主要讨论第一种情况,它们保存指向动态分配对象的指针,并在正确的时候删除这些对象. 何时我们需要智能指针? 有三种典型的情况适合使用智能指针: ? 资源所有权的共享 ? 要写异常安全的代码时 ? 避免常见的错误,如资源泄漏 共享所有权,当多个对象需要同时使用第三个对象的情

C++ 智能指针(一)

内存安全 在C++中,动态内存的管理是通过一对运算符来完成的:new,在动态内存中为对象分配空间并返回一个指向该对象的指针,我们可以选择对对象来进行初始化:delete,接收一个动态对象的指针,销毁该对象,并释放与之关联的内存. 动态内存的使用很容易出问题,因为确保在正确的时间释放内存是及其困难的.有时我们会忘记释放内存(或程序抛出异常),在这种情况下就会产生内存泄漏:有时在尚有指针引用内存的情况下我们就释放了它,在这种情况下就会产生引用非法内存的指针(段错误). 下面写个Demo测试程序 #i

【C++】智能指针详解(三):scoped_ptr

在介绍scoped_ptr之前,我们先回顾一下前两篇文章的内容. 首先,智能指针采用RAII机制,通过对象来管理指针,构造对象时,完成资源的初始化;析构对象时,对资源进行清理及汕尾. auto_ptr,通过转移管理权来完成对象的拷贝与赋值,在实际开发中并不实用. 回顾完智能指针的背景及auto_ptr的特性之后,本文来介绍scoped_ptr的实现原理及特性. scoped_ptr与auto_ptr类似,但最大的区别就是它不能转让管理权.也就是说,scoped_ptr禁止用户进行拷贝与赋值. 诶