您的位置:首页 > 其它

带引用计数的智能指针(模板类)实现的3种方法

2013-07-25 17:30 447 查看
转载自:http://www.cppblog.com/playerken/archive/2011/08/10/152990.html

1. 非侵入式:static map<unsigned int, int>,key是对象地址,value是counter。

2. 非侵入式:构造函数new一个int作为counter,拷贝构造函数和赋值操作符中传递该counter。

3. 侵入式:定义一个Count基类自带counter,所有对象继承与Count基类,counter在对象中。

方法2无法重载 operator = (T *t),因为无法从参数中获得t的counter信息。

Code1: 用static map作为counter

#include <stdio.h>
#include <map>

using namespace std;

class A
{
public:
A()
{
printf("\nA Construct\n");
}

~A()
{
printf("\nA Destruct\n");
}
};

class B
{
public:
B()
{
printf("\nB Construct\n");
}

~B()
{
printf("\nB Destruct\n");
}
};

template <typename T>
class SmartPtr
{
public:
SmartPtr(T *t)
{
Pointee = t;

map<unsigned int, int>::iterator it = CountMap.find((unsigned int)t);
if(it != CountMap.end())
++(it->second);
else
CountMap[(unsigned int)Pointee] = 1;
}

SmartPtr(const SmartPtr &sp)
{
Pointee = sp.Pointee;

map<unsigned int, int>::iterator it = CountMap.find((unsigned int)Pointee);
if(it != CountMap.end())
++(it->second);
else
CountMap[(unsigned int)Pointee] = 1;
}

SmartPtr& operator = (const SmartPtr &sp)
{
if(NULL != Pointee)
{
--CountMap[(unsigned int)Pointee];
if(CountMap[(unsigned int)Pointee] == 0)
{
CountMap.erase((unsigned int)Pointee);
delete Pointee;
Pointee = NULL;
}
}

Pointee = sp.Pointee;

map<unsigned int, int>::iterator it = CountMap.find((unsigned int)Pointee);
if(it != CountMap.end())
++(it->second);
else
CountMap[(unsigned int)Pointee] = 1;

return *this;
}

SmartPtr& operator = (T *t)
{
if(NULL != Pointee)
{
--CountMap[(unsigned int)Pointee];
if(CountMap[(unsigned int)Pointee] == 0)
{
CountMap.erase((unsigned int)Pointee);
delete Pointee;
Pointee = NULL;
}
}

Pointee = t;

map<unsigned int, int>::iterator it = CountMap.find((unsigned int)Pointee);
if(it != CountMap.end())
++(it->second);
else
CountMap[(unsigned int)Pointee] = 1;

return *this;
}

~SmartPtr()
{
if(NULL != Pointee)
{
--CountMap[(unsigned int)Pointee];
if(CountMap[(unsigned int)Pointee] == 0)
{
CountMap.erase((unsigned int)Pointee);
delete Pointee;
Pointee = NULL;
}
}
}
private:
T *Pointee;
static map<unsigned int, int> CountMap;
SmartPtr();
};

template <typename T>
map<unsigned int, int> SmartPtr<T>::CountMap;

int main()
{
A *objA1 = new A();
A *objA2 = new A();
A *objA3 = new A();
B *objB1 = new B();
B *objB2 = new B();
B *objB3 = new B();

SmartPtr<A> sPtrA1(objA1);
SmartPtr<A> sPtrA2(objA2);
sPtrA1 = sPtrA2;
sPtrA1 = objA3;
sPtrA2 = objA3;

SmartPtr<B> sPtrB1(objB1);
SmartPtr<B> sPtrB2(objB2);
sPtrB1 = sPtrB2;
sPtrB1 = objB3;
sPtrB2 = objB3;
return 0;
}

Code2: 用new int作为counter

#include <stdio.h>

class A
{
public:
A()
{
printf("\nA Construct\n");
}

~A()
{
printf("\nA Destruct\n");
}
};

class B
{
public:
B()
{
printf("\nB Construct\n");
}

~B()
{
printf("\nB Destruct\n");
}
};

template <typename T>
class SmartPtr
{
public:
SmartPtr(T *t)
{
Pointee = t;

Count = new int(0);
++(*Count);
}

SmartPtr(const SmartPtr &sp)
{
Pointee = sp.Pointee;
Count = sp.Count;
++(*Count);
}

SmartPtr& operator = (const SmartPtr &sp)
{
if(NULL != Pointee)
--(*Count);
if(*Count == 0)
delete Pointee;

Pointee = sp.Pointee;
Count = sp.Count;
++(*Count);

return *this;
}

// Cannot work well.
// Should not public this method.
SmartPtr& operator = (T *t)
{
if(NULL != Pointee)
--(*Count);
if(*Count == 0)
{
delete Pointee;
delete Count;
}
Pointee = t;
// Cannot get the counter on t.
Count = new int(0);
++(*Count);

return *this;
}

~SmartPtr()
{
if(NULL != Pointee)
--(*Count);
if(*Count == 0)
{
delete Pointee;
Pointee = NULL;
}
delete Count;
}
private:
T *Pointee;
int *Count;
SmartPtr();
};

int main()
{
A *obj1 = new A();
A *obj2 = new A();
A *obj3 = new A();
B *objB1 = new B();
B *objB2 = new B();
B *objB3 = new B();

SmartPtr<A> sPtr1(obj1);
SmartPtr<A> sPtr2(obj2);
sPtr1 = sPtr2;
sPtr1 = obj3;
// Comment out since SmartPtr cannot get the existing counter on obj3.
//sPtr2 = obj3;

SmartPtr<B> sPtrB1(objB1);
SmartPtr<B> sPtrB2(objB2);
sPtrB1 = sPtrB2;
sPtrB1 = objB3;
// Comment out since SmartPtr cannot get the existing counter on objB3.
//sPtrB2 = objB3;
return 0;
}

Code3: 对象继承与Count基类,counter在对象内

#include <stdio.h>

class ReferenceCount
{
public:
virtual ~ReferenceCount(){};
int Count;
protected:
ReferenceCount():Count(0){};
};

class Intrusive: public ReferenceCount
{
public:
Intrusive()
{
printf("\nInstrusive Construct\n");
}

~Intrusive()
{
printf("\nInstrusive Destruct\n");
}
};

class B: public ReferenceCount
{
public:
B()
{
printf("\nB Construct\n");
}

~B()
{
printf("\nB Destruct\n");
}
};

template <typename T>
class SmartPtrIntrusive
{
public:
SmartPtrIntrusive(T *t)
{
Pointee = t;
++Pointee->Count;
}

SmartPtrIntrusive(const SmartPtrIntrusive &sp)
{
Pointee = sp.Pointee;
++Pointee->Count;
}

SmartPtrIntrusive& operator = (const SmartPtrIntrusive &sp)
{
if(NULL != Pointee)
--Pointee->Count;
if(Pointee->Count == 0)
{
delete Pointee;
Pointee = NULL;
}

Pointee = sp.Pointee;
++Pointee->Count;

return *this;
}

SmartPtrIntrusive& operator = (T *t)
{
if(NULL != Pointee)
--Pointee->Count;
if(Pointee->Count == 0)
{
delete Pointee;
Pointee = NULL;
}

Pointee = t;
++Pointee->Count;

return *this;
}

~SmartPtrIntrusive()
{
if(NULL != Pointee)
--Pointee->Count;
if(Pointee->Count == 0)
{
delete Pointee;
Pointee = NULL;
}
}
private:
T *Pointee;
SmartPtrIntrusive();
};

int main()
{
Intrusive *obj1 = new Intrusive();
Intrusive *obj2 = new Intrusive();
Intrusive *obj3 = new Intrusive();
B *objB1 = new B();
B *objB2 = new B();
B *objB3 = new B();
SmartPtrIntrusive<Intrusive> sPtr1(obj1);
SmartPtrIntrusive<Intrusive> sPtr2(obj2);
sPtr1 = sPtr2;
sPtr1 = obj3;
sPtr2 = obj3;

SmartPtrIntrusive<B> sPtrB1(objB1);
SmartPtrIntrusive<B> sPtrB2(objB2);
sPtrB1 = sPtrB2;
sPtrB1 = objB3;
sPtrB2 = objB3;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: