智能指针:它的一种通用实现方法是采用引用计数的方法。智能指针将一个计数器与类指向的对象相关联,引用计数跟踪共有多少个类对象共享同一指针。
每次创建类的新对象时,初始化指针并将引用计数置为1;
当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;
对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;这是因此左侧的指针指向了右侧指针所指向的对象,因此右指针所指向的对象的引用计数+1;
调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。
实现智能指针有两种经典策略:一是引入辅助类,二是使用句柄类。
namespace smart
{
// 引用计数类.
class smart_count
{
public:
smart_count(int c = 0) : use_count(c) {}
~smart_count() {}
// 增加引用计数, 并返回计数值.
int addref() {
return ++use_count;
}
// 减少引用计数, 并返回计数值.
int release() {
return --use_count;
}
private:
// 计数变量.
int use_count;
};
// 智能指针.
template<class T>
class
smart_ptr
{
public:
// 构造指针, 并使引用计数置为1.
explicit
smart_ptr(T* ptr) : p(ptr), u(new smart_count(1))
{}
// 构造空指针.
explicit
smart_ptr() : p(NULL), u(NULL)
{}
// 智能指针析构.
~smart_ptr(void)
{
// 如果引用计数等于0, 则删除数据和引用计数, 并置p为NULL.
// 此处需要注意的是, 共用的u并未置为 NULL, 在其它指针析构
// 时, p为NULL, 则不会重复delete.
if
(p && u->release() <= 0)
{
delete p;
delete u;
p = NULL;
}
}
// 智能指针拷贝构造函数.
smart_ptr(const smart_ptr<T>& t)
{
p = t.p;
u = t.u;
if(u) // 必须判断空值.
{
u->addref(); // 增加引用计数.
}
}
// 指针赋值.
void operator= (smart_ptr<T>& t)
{
// 首先将引用计数减1, 然后再判断是否小于0, 如果小于0, 则delete.
if(p && u->release() <= 0)
{
delete p;
delete u;
}
// 直接赋值.
p = t.p;
u = t.u;
if(u) // 必须判断空值.
{
u->addref(); // 增加引用计数.
}
}
// 重载->操作和*操作符.
T *operator-> (void) {
return p;
}
T& operator *(void) {
return *p;
}
// 重载!操作符.
bool operator! () const
{
return !p;
}
// 重载指针bool值操作符.
typedef smart_ptr<T> this_type;
typedef T * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const
{
return !p ? 0 : &this_type::p;
}
// 得到原指针.
T* get() {
return p;
}
void reset(T* ptr)
{
// 首先将引用计数减1, 然后再判断是否小于0, 如果小于0, 则delete.
if (p && u->release() <= 0)
{
delete p;
delete u;
}
// 赋值, 如果是NULL, 则不创建引用计数.
p = ptr;
if(p)
u = new smart_count(1);
else
u = NULL;
}
void reset(smart_ptr<T>& t)
{
// 首先将引用计数减1, 然后再判断是否小于0, 如果小于0, 则delete.
if
(p && u->release() <= 0)
{
delete p;
delete u;
}
// 赋值.
p = t.p;
u = t.u;
if(u) // 必须判断空值.
{
u->addref(); // 增加引用计数.
}
}
private:
T* p;
smart_count* u;
};
// 重载==操作符.
template<class T, class U> inline
bool operator==(smart_ptr<T> & a, smart_ptr<U> & b)
{
return a.get() == b.get();
}
// 重载!=操作符.
template<class T, class U> inline
bool operator!=(smart_ptr<T> & a, smart_ptr<U> & b)
{
return a.get() != b.get();
}
}
3, 智能指针的实现
下面是一个基于引用计数的智能指针的实现,需要实现构造,析构,拷贝构造,=操作符重载,重载*-和>操作符。
[cpp] view plain copy
template <typename T>
class SmartPointer {
public:
//构造函数
SmartPointer(T* p=0): _ptr(p), _reference_count(new size_t){
if(p)
*_reference_count = 1;
else
*_reference_count = 0;
}
//拷贝构造函数
SmartPointer(const SmartPointer& src) {
if(this!=&src) {
_ptr = src._ptr;
_reference_count = src._reference_count;
(*_reference_count)++;
}
}
//重载赋值操作符
SmartPointer& operator=(const SmartPointer& src) {
if(_ptr==src._ptr) {
return *this;
}
releaseCount();
_ptr = src._ptr;
_reference_count = src._reference_count;
(*_reference_count)++;
return *this;
}
//重载操作符
T& operator*() {
if(ptr) {
return *_ptr;
}
//throw exception
}
//重载操作符
T* operator->() {
if(ptr) {
return _ptr;
}
//throw exception
}
//析构函数
~SmartPointer() {
if (--(*_reference_count) == 0) {
delete _ptr;
delete _reference_count;
}
}
private:
T *_ptr;
size_t *_reference_count;
void releaseCount() {
if(_ptr) {
(*_reference_count)--;
if((*_reference_count)==0) {
delete _ptr;
delete _reference_count;
}
}
}
};
int main()
{
SmartPointer<char> cp1(new char('a'));
SmartPointer<char> cp2(cp1);
SmartPointer<char> cp3;
cp3 = cp2;
cp3 = cp1;
cp3 = cp3;
SmartPointer<char> cp4(new char('b'));
cp3 = cp4;
}