//前置声明 因为在使用sharedptr时可能会产生循环引用的缺陷,所以使用weakedptr进行辅助
template <class T>
class WeakedPtr;
template<class T>
class MySharedPtr
{
public:
//定义为友元类
     friend class WeakedPtr<T>;
     MySharedPtr(T* ptr =  NULL) :_ptr(ptr), _refCount(new int(1))
     {}
     ~MySharedPtr()
     {
          if (--(*_refCount) == 0)
          {
              delete _ptr;
              delete _refCount;
          }
     }
     //s1(s2)
     MySharedPtr(const MySharedPtr<T>& sp) :_ptr(sp._ptr), _refCount(sp._refCount)
     {
          (*_refCount)++;
     }
     //sp1 = sp2
     MySharedPtr<T>& operator=(MySharedPtr<T>& sp)
     {
              if (_ptr != sp._ptr)
              {
                   if (--(*_refCount) == 0)
                   {
                        delete _ptr;
                        delete _refCount;
                   }
                   _ptr = sp._ptr;
                   _refCount = sp._refCount;
                   (*_refCount)++;
              }
          return *this;
     }
     //为了像指针一样才进行*\->的重载
     //->的重载
     T* operator->()
     {
          return _ptr;
     }
     //*的重载
     T& operator*()
     {
          return *_ptr;
     }
     //查看引用计数的多少
     int UseCount()
     {
          return *_refCount;
     }
private:
     T* _ptr;
     int* _refCount;//一块空间有一个指针
};
template <class T>
class WeakedPtr
{
public:
     WeakedPtr() :_ptr(NULL)
     {}
     WeakedPtr(const MySharedPtr<T>& sp)
          :_ptr(sp._ptr)
     {}
     WeakedPtr<T>& operator=(const MySharedPtr<T>&sp)
     {
          _ptr = sp._ptr;
          return *this;
     }
     T& operator* ()
     {
          return *_ptr;
     }
     T* operator->()
     {
          return _ptr;
     }
private:
     T* _ptr;
};
struct  ListNode
{
     int _data;
     WeakedPtr<ListNode> _next;
     WeakedPtr<ListNode> _prev;
     ~ListNode()
     {
          cout << "~ListNode" << endl;
     }
};
void testMySharedPtr()
{
     //SharePtr<int> sp1(new int(1));
     //SharePtr<int> sp2(sp1);
     MySharedPtr<ListNode> cur(new ListNode);
     MySharedPtr<ListNode> next(new ListNode);
     cout << cur.UseCount() << endl;
     cout << next.UseCount() << endl;
     cur->_next = next;
     next->_prev = cur;
     cout << cur.UseCount() << endl;
     cout << next.UseCount() << endl;
}