带引用计数的智能指针(模板类)
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
Code2: 用new int作为counter
Code3: 对象继承与Count基类,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 ;
}
#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 ;
}
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 ;
}
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 ;
}