以下案例只是一个简单的小程序,实现过程中主要是将辅助计数类当做共有的属性
#include <iostream>
using namespace std;
template <class T>
class adv_smart_pointer;
template <class T>
class ref_cnt
{
friend class adv_smart_pointer<T>;
public:
ref_cnt(T *p) : data_pointer(p), cnt(1)
{}
~ref_cnt()
{
if (data_pointer)
{
delete data_pointer;
cnt = 0;
data_pointer = NULL;
}
}
private:
T *data_pointer;
int cnt;
};
template <class T>
class adv_smart_pointer
{
public:
adv_smart_pointer() : cnt_pointer(NULL)
{}
adv_smart_pointer(T *p) : cnt_pointer(new ref_cnt<T>(p))
{}
~adv_smart_pointer()
{
if (cnt_pointer)
{
if (cnt_pointer->cnt > 0)
{
--cnt_pointer->cnt;
if (cnt_pointer->cnt == 0)
{
delete cnt_pointer;
cnt_pointer = NULL;
}
}
}
}
adv_smart_pointer(const adv_smart_pointer& obj)
{
if (&obj != NULL)
{
cnt_pointer = obj.cnt_pointer;
cnt_pointer->cnt ++;
}
}
adv_smart_pointer &operator=(adv_smart_pointer &obj)
{
if (this != &obj)
{
if (cnt_pointer && cnt_pointer->cnt > 0)
{
cnt_pointer->cnt --;
if (cnt_pointer->cnt == 0)
{
delete cnt_pointer;
cnt_pointer = NULL;
}
}
cnt_pointer = obj.cnt_pointer;
cnt_pointer->cnt ++;
}
return *this;
}
T *operator->()
{
if (cnt_pointer )
{
return cnt_pointer->data_pointer;
}
else
{
return NULL;
}
}
T &operator*()
{
if (cnt_pointer)
{
return *(cnt_pointer->data_pointer);
}
else
{
throw "reference to NULL";
}
}
private:
ref_cnt<T> *cnt_pointer;
};
class adv_test
{
public:
adv_test() : index(100)
{
cout << "adv test print" << endl;
}
~adv_test()
{
cout << "destruct test print" << index << endl;
}
void set_index(int index)
{
this->index = index;
}
void show()
{
cout << "adv test hello" << index << endl;
}
private:
int index;
};
void obj_play_4()
{
adv_smart_pointer<adv_test> pointer1(new adv_test);
adv_smart_pointer<adv_test> pointer2 = pointer1;
adv_smart_pointer<adv_test> pointer3 = pointer2;
adv_smart_pointer<adv_test> pointer4 = pointer3;
pointer1 = pointer4;
pointer1->set_index(80);
pointer1->show();
adv_smart_pointer<adv_test> new_pointer1(new adv_test);
pointer1 = new_pointer1;
pointer1->show();
pointer4->show();
}
int main()
{
obj_play_4();
return 0;
}