AutoPtr
资源的转移不推荐使用。
旧库使用拥有者会导致野指针
实现代码
template <class T>
class AutoPtr
{
public:
AutoPtr(T* p = NULL)
: _ptr(p)
{}
AutoPtr(AutoPtr<T>& ap)
:_ptr(ap._ptr)
{
ap._ptr = NULL;
}
AutoPtr<T>& operator=(AutoPtr<T>& ap)
{
if (this != &ap)
{
delete _ptr;
_ptr = ap._ptr;
ap._ptr = NULL;
}
return *this;
}
~AutoPtr()
{
if (_ptr)
{
delete _ptr;
_ptr = NULL;
}
}
T* GetPtr()
{
return _ptr;
}
const T* GetPtr()const
{
return _ptr;
}
T& operator*()
{
return *_ptr;
}
const T& operator*()const
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
const T* operator->()const
{
return _ptr;
}
private:
T* _ptr;
};
测试用例
void Test_AutoPtr()
{
/*
* 测试构造函数拷贝拷贝构造
*/
AutoPtr<int> ap1(new int(20));
std::cout << *ap1 << std::endl;
AutoPtr<int> ap2(ap1);
std::cout << *ap2 << std::endl;
/*
* 测试 operator = 和 -> *
*/
struct A
{
int a;
int b;
};
AutoPtr<A> ap3(new A);
ap3->a = 2;
ap3->b = 3;
std::cout << (*ap3).a << std::endl;
std::cout << (*ap3).b << std::endl;
AutoPtr<A> ap4;
ap4 = ap3;
std::cout << (*ap4).a << std::endl;
std::cout << (*ap4).b << std::endl;
}
输出结果
20
20
2
3
2
3
ScopedPtr / Unique_ptr
unique_ptr 是 c++11 标识, ScopedPtr 是 boost库提供 还有ScopedAarray
实现代码
template <class T>
class ScopedPtr
{
public:
ScopedPtr(T* p = NULL)
: _ptr(p)
{}
~ScopedPtr()
{
if (_ptr)
{
delete _ptr;
_ptr = NULL;
}
}
T* operator->()
{
return _ptr;
}
const T* operator->()const
{
return _ptr;
}
T& operator*()
{
return *_ptr;
}
const T& operator*()const
{
return *_ptr;
}
T* GetPtr()
{
return _ptr;
}
const T* GetPtr()const
{
return _ptr;
}
private:
ScopedPtr(const ScopedPtr<T>&);
ScopedPtr<T>& operator=(const ScopedPtr<T>&);
private:
T* _ptr;
};
测试用例
void Test_ScopedPtr()
{
ScopedPtr<int> sp1(new int(20));
std::cout << *sp1 << std::endl;
//ScopedPtr<int> sp2(sp1); // error 拷贝构造函数为私有
ScopedPtr<int> sp3(new int(30));
//sp3 = sp1; // error 赋值运算符私有 方式拷贝
struct A
{
int a;
int b;
};
ScopedPtr<A> sp4(new A);
sp4->a = 1;
sp4->b = 2;
std::cout << (*sp4).a << std::endl;
std::cout << (*sp4).b<< std::endl;
}
输出结果
20
1
2
ScopedArray
实现代码
template <class T>
class ScopedArray
{
public:
ScopedArray(T* p = NULL)
: _ptr(p)
{}
~ScopedArray()
{
if (_ptr)
{
delete[] _ptr;
_ptr = NULL;
}
}
T& operator[](size_t index)
{
return _ptr[index];
}
const T& operator[](size_t index)const
{
return _ptr[index];
}
private:
ScopedArray(const ScopedArray<T>&);
ScopedArray<T>& operator=(const ScopedArray<T>&);
private:
T* _ptr;
};
测试用例
void Test_ScopedArray()
{
ScopedArray<int> spa1(new int[10]);
spa1[0] = 20;
std::cout << spa1[0] << std::endl;
ScopedArray<int> spa2(new int[20]);
// spa2 = spa1; // error ,operator = 为私有
// ScopedArray<int> spa3(spa1); // error 拷贝构造为私有
struct A
{
int a;
int b;
};
ScopedArray<A> spa4(new A[10]);
spa4[0].a = 1;
spa4[0].b = 2;
std::cout << spa4[0].a << std::endl;
std::cout << spa4[0].b << std::endl;
}
输出结果
20
1
2
SharedPtr
存在的问题,循环引用,weak_ptr解决。他不会占用引用计数,必须用一个sharedptr来赋值。
shared 定制删除器。 C++11 提供了 shared_ptr。Boost提供了shared_ptr 和 sharedarray。
实现代码
template <class T>
class SharedPtr
{
public:
explicit SharedPtr(T* p = NULL)
: _ptr(p)
, _pcount(new unsigned int(1))
{}
explicit SharedPtr(const SharedPtr<T>& sp)
:_ptr(sp._ptr)
, _pcount(sp._pcount)
{
++(*_pcount);
}
SharedPtr<T>& operator=(const SharedPtr<T>& sp)
{
if (this != &sp)
{
if ((--(*_pcount)) == 0)
{
delete _pcount;
delete _ptr;
}
_ptr = sp._ptr;
_pcount = sp._pcount;
++(*_pcount);
}
return *this;
}
~SharedPtr()
{
if ((--(*_pcount)) == 0)
{
delete _ptr;
delete _pcount;
}
}
unsigned int UseCount()const
{
return *_pcount;
}
T& operator*()
{
return *_ptr;
}
const T& operator*()const
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
const T* operator->()const
{
return _ptr;
}
T* GetPtr()
{
return _ptr;
}
const T* GetPtr()const
{
return _ptr;
}
private:
T* _ptr;
unsigned int* _pcount;
};
测试用例
void Test_ShareddPtr()
{
SharedPtr<int> sp1(new int(2));
sp1 = sp1;
std::cout << sp1.UseCount() << std::endl;
std::cout << *sp1 << std::endl;
SharedPtr<int> sp2(sp1);
std::cout << sp1.UseCount() << std::endl;
SharedPtr<int> sp3;
sp3 = sp1;
std::cout << sp1.UseCount() << std::endl;
SharedPtr<int> sp4(new int(4));
std::cout << sp4.UseCount() << std::endl;
sp4 = sp1;
std::cout << sp4.UseCount() << std::endl;
std::cout << sp1.UseCount() << std::endl;
}
输出结果
1
2
2
3
1
4
4