#include <iostream>
#include <string>
#define unsigned int size_t
using namespace std;
// 未考虑线程安全
template<typename FriendClass, typename DataType>
class RefCount{
private:
DataType * IPtr;
size_t count;
RefCount(DataType * p):IPtr(p),count(0){
print("构造函数");
}
~RefCount(){
print("析构函数");
delete IPtr;
IPtr = NULL;
}
void increaseOne(){
this->count ++;
}
void decreaseOne(){
this->count --;
}
void print(string info){
cout << "RefCount:"<<info<<" Refcount:"<<count<<endl;
}
friend FriendClass;
};
template<typename DataType>
class SmartPtr{
private:
RefCount<SmartPtr,DataType> * ptr;
public:
SmartPtr( DataType * p):ptr(new RefCount<SmartPtr,DataType>(p)){
ptr->increaseOne();
print("构造函数");
}
SmartPtr(const SmartPtr& rhs):ptr(rhs.ptr){
ptr->increaseOne();
print("复制构造函数");
}
SmartPtr & operator =(const SmartPtr & rhs){
if(this == &rhs) return *this;
set(rhs.ptr);
print("赋值操作符函数");
return *this;
}
DataType & operator *(){
return * (ptr->IPtr);
}
DataType * operator ->(){
return ptr->IPtr;
}
DataType * getPtr(){
return ptr->IPtr;
}
DataType getValue(){
return *(ptr->IPtr);
}
void setPtr(DataType * newPtr){
if(newPtr == NULL) return;
this->set(new RefCount<SmartPtr,DataType>(newPtr));
}
void setValue(DataType newValue){
*(ptr->IPtr) = newValue;
}
~SmartPtr(){
print("析构函数");
reset();
}
void print(string info){
cout << "SmartPtr:"<<info<<" Value: "<<*(ptr->IPtr)<<" RefCount:"<<ptr->count<<endl;
}
private:
void set(RefCount<SmartPtr,DataType> * newPtr){
reset();
ptr = newPtr;
ptr->increaseOne();
}
void reset(){
ptr->decreaseOne();
if(ptr->count == 0)
delete ptr;
ptr=NULL;
}
};
int main()
{
//测试普通构造函数
{
SmartPtr<int> sp(new int(1));
/* 输出
RefCount:构造函数 Refcount:0
SmartPtr:构造函数 Value: 1 RefCount:1
SmartPtr:析构函数 Value: 1 RefCount:1
RefCount:析构函数 Refcount:0
*/
}
//测试复制构造函数
{
SmartPtr<int> sp(new int(2));
SmartPtr<int> sp1(sp);
/*输出
RefCount:构造函数 Refcount:0
SmartPtr:构造函数 Value: 2 RefCount:1
SmartPtr:复制构造函数 Value: 2 RefCount:2
SmartPtr:析构函数 Value: 2 RefCount:2
SmartPtr:析构函数 Value: 2 RefCount:1
RefCount:析构函数 Refcount:0
*/
}
// 测试赋值操作符
{
SmartPtr<int> sp(new int(3)),sp1(new int(4));
sp = sp1;
/* 输出
RefCount:构造函数 Refcount:0
SmartPtr:构造函数 Value: 3 RefCount:1
RefCount:构造函数 Refcount:0
SmartPtr:构造函数 Value: 4 RefCount:1
RefCount:析构函数 Refcount:0
SmartPtr:赋值操作符函数 Value: 4 RefCount:2
SmartPtr:析构函数 Value: 4 RefCount:2
SmartPtr:析构函数 Value: 4 RefCount:1
RefCount:析构函数 Refcount:0
*/
}
//测试* ->操作符
{
SmartPtr<string> sp( new string("helloworld"));
cout << *sp <<endl;
sp->append(" 你好!");
cout << sp->c_str()<<endl;
*sp = "哈哈哈";
cout << sp.getValue()<<endl;
/*输出
RefCount:构造函数 Refcount:0
SmartPtr:构造函数 Value: helloworld RefCount:1
helloworld
helloworld 你好!
哈哈哈
SmartPtr:析构函数 Value: 哈哈哈 RefCount:1
RefCount:析构函数 Refcount:0
*/
}
//其他函数测试
{
SmartPtr<int> sp(new int(5));
cout << *(sp.getPtr())<<endl;
sp.setPtr(new int(6));
cout <<sp.getValue()<<endl;
sp.setValue(7);
cout << *sp<<endl;
/*输出
RefCount:构造函数 Refcount:0
SmartPtr:构造函数 Value: 5 RefCount:1
5
RefCount:构造函数 Refcount:0
RefCount:析构函数 Refcount:0
6
7
SmartPtr:析构函数 Value: 7 RefCount:1
RefCount:析构函数 Refcount:0
*/
}
// 内存泄露测试
{
while(true){ //在任务管理器中观察内存占用情况
int *p = new int(3);
int *q =new int(4);
SmartPtr<int> sp1(p);
SmartPtr<int> sp3=sp1;
sp3.setPtr(q);
SmartPtr<int> sp4=sp3;
SmartPtr<int> sp5(new int(5));
sp1= sp5;
sp3=sp5;
sp4=sp5;
sp5.setPtr(new int(6));
int * pi = new int(8);
SmartPtr<int> *spa= new SmartPtr<int>(pi);
SmartPtr<int> *spb = new SmartPtr<int>(*spa);
SmartPtr<int> *spc = new SmartPtr<int>(*spb);
delete spa;
delete spb;
delete spc;
}
}
}