引入:定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理。
boost库的智能指针
auto_ptr:资源转移,当使用拷贝构造,赋值操作时将资源转移,并将自己的资源置为空
加权限,当使用拷贝构造,赋值操作时资源不释放,只是将权限改为false,当权限为true时&&资源不为空时,才可以释放资源。
scoped_ptr:将拷贝构造,赋值操作设置为私有的或者保护的.
shared_ptr:采用引用计数的方式实现,每个对象都私有一个计数区域,表示多少个对象指向它。只有当_ptr不为空并且计数为1时才可以释放资源。
存在的线程安全问题
1. 同一个shared_ptr对象可以被多线程同时读取。
2. 不同的shared_ptr对象可以被多线程同时修改。
3. 同一个shared_ptr对象不能被多线程直接修改,但可以通过原子函数完成。
实现代码
#define _CRT_SECURE_NO_WARNINGS
#include
using namespace std;
//auto_ptr权限转移
template<class T>
class AutoPtr
{
private:
T* _ptr;
public:
AutoPtr(T* ptr = NULL)
:_ptr(ptr)
{}
AutoPtr(AutoPtr& at)
:_ptr(at._ptr)
{
at._ptr = NULL;
}
AutoPtr& operator=(AutoPtr& at)
{
if (this != &at)
{
delete _ptr;
_ptr = at._ptr;
at._ptr = NULL;
}
return *this;
}
T& operator*()const
{
return *(_ptr);
}
T* operator->()const
{
return _ptr;
}
~AutoPtr()
{
if (_ptr != NULL)
{
delete _ptr;
_ptr = NULL;
}
cout << "~AutoPtr()" << endl;
}
};
template<class T>
class AutoPtrTwo
{
private:
T* _ptr;
mutable bool _owner;//加权限,当有权限时才能释放资源,否则不可以
public:
AutoPtrTwo(T* ptr = NULL)
:_ptr(ptr)
, _owner(true)
{}
AutoPtrTwo(const AutoPtrTwo& at)
:_ptr(at._ptr)
, _owner(true)
{
at._owner = false;
}
AutoPtrTwo& operator=(const AutoPtrTwo& at)
{
if (this != &at)
{
if (_owner)
delete _ptr;
_ptr = at._ptr;
_owner = at._owner;
at._owner = false;
}
return *this;
}
T& operator*()const
{
return *(_ptr);
}
T* operator->()const
{
return _ptr;
}
~AutoPtrTwo()
{
if (_ptr && _owner)
{
delete _ptr;
_ptr = NULL;
}
cout << "~AutoPtrTwo()" << endl;
}
};
//scoped_ptr,防拷贝实现
template<class T>
class ScopedPtr
{
private:
T* _ptr;
private:
ScopedPtr(const ScopedPtr& sp);
ScopedPtr& operator=(const ScopedPtr& sp);
public:
ScopedPtr(T* ptr = NULL)
:_ptr(ptr)
{}
T& operator*()const
{
return *(_ptr);
}
T* operator->()const
{
return _ptr;
}
~ScopedPtr()
{
if (_ptr)
{
delete _ptr;
_ptr = NULL;
}
}
};
//shared_ptr,采用引用计数
template<class T>
class SharedPtr
{
private:
T* _ptr;
mutable int* _pCount;
public:
SharedPtr(T* ptr = NULL)
:_ptr(ptr)
{
if (_ptr)
_pCount = new int(1);
}
SharedPtr(const SharedPtr& sdp)
:_ptr(sdp._ptr)
, _pCount(new int(1))
{
++(*_pCount);
}
SharedPtr& operator=(const SharedPtr& sdp)
{
if (this != &sdp)
{
// if (_ptr && (--(*_pCount) == 0))
// {
// delete _ptr;
// _ptr = NULL;
// delete _pCount;
// _pCount = NULL;
// }
Realease();
++*(sdp._pCount);
}
return *this;
}
T& operator*()const
{
return *(_ptr);
}
T* operator->()const
{
return _ptr;
}
~SharedPtr()
{
Realease();
cout << "~SharedPtr()" << endl;
}
private:
void Realease()
{
if ((_ptr) && (--(*this->_pCount) == 0))
{
delete _pCount;
_pCount = NULL;
delete _ptr;
_ptr = NULL;
}
}
};
测试代码
#include "Ptr.hpp"
void TestAutoPtr()
{
int a = 10;
int* p=&a;
AutoPtr<int> at;
AutoPtr<int> at1(p);
AutoPtr<int> at2(at1);
at = at2;
}
void TestAutoPtrTwo()
{
int b = 20;
int* pt = &b;
AutoPtrTwo<int> att;
AutoPtrTwo<int> att1(pt);
AutoPtrTwo<int> att2(att1);
att = att2;
}
void TestSocpedPtr()
{
//int a = 30;
int* p3 = new int(14);
//int *p3 = &a;
ScopedPtr<int> sp;
ScopedPtr<int> sp1(p3);
cout << *sp1 << endl;
}
void TestSharedPtr()
{
int* p4 = new int(50);
SharedPtr<int> sdp;
SharedPtr<int> sdp1(p4);
SharedPtr<int> sdp2(sdp1);
sdp = sdp2;
}
int main()
{
//TestAutoPtr();
//TestAutoPtrTwo();
//TestSocpedPtr();
TestSharedPtr();
return 0;
}