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;
}