#define  _CRT_SECURE_NO_WARNINGS

#include<iostream>
using namespace std;
template<class T>
class Auto_ptr
{
public:
 Auto_ptr(T* _x) :x(_x)
 {}
 Auto_ptr(Auto_ptr<T> &s) :x(s.x)
 {

  s.x = NULL;
 }
 Auto_ptr& operator=(Auto_ptr<T> &s)
 {
  x = s.x;
  s.x = NULL;
  
 }
 ~Auto_ptr()
 {

 }

private:
 T* x;


};

//template<class T>
//class Shared_ptr
//{
//public:
// Shared_ptr(T* _x=NULL) :x(_x), p(new int(0))
// {
//  ++*p;
// }
// Shared_ptr(Shared_ptr<T> &s) :x(s.x)
// {
//  ++*(s.p);
//  p = s.p;
// }
//
// Shared_ptr<T>& operator=(Shared_ptr<T> &s)
// {
//  if (this->x != s.x)
//  {
//   --*p;
//   x = s.x;
//   p = s.p;
//   ++*p;
//   return *this;
//  }
//
// }
// void Realease()
// {
//  delete x;
//  delete p;
//
// }
//
// ~Shared_ptr()
// {
//  if (--*p==0)
//  {
//   Realease();
//  }
// }
//
//private:
// T* x;
// int *p;
//
//
//};


template<class T>
class Scoped_ptr
{
public:
 Scoped_ptr(T *x) :_x(x), p(new int(1))
 {}
 
private:
 Scoped_ptr(const Scoped_ptr &s);
 Scoped_ptr operator=(const Scoped_ptr &s);
 
private:
 T* _x;
 int *p;
};

template<class T>
struct Del
{
 void operator()(const T* ptr)
 {
  cout << "Del" <<ptr<< endl;
  delete ptr;
 }
};

template<class T>
struct FFF
{
 void operator()(const T* ptr)
 {
  cout << "delete[]" << endl;
  delete[] ptr;
 }
};

struct Free//仿函数
{
 void operator() (void* ptr)
 {
  cout << "free:" << ptr << endl;
  free(ptr);
 }
};

struct Fclose
{
 void operator() (void* ptr)
 {
  cout << "fclose:" << ptr << endl;
  fclose((FILE*)ptr);
 }
};

template<class T,class Deleter =Del<T> >
class Shared_ptr
{
public:
 Shared_ptr(T *ptr) :_ptr(ptr), _refcount(new long(1))
 {}
 Shared_ptr(T *ptr, Deleter del) :_ptr(ptr), _refcount(new long(1)), _del(del)
 {}
 ~Shared_ptr()
 {
  Realease();
 }
 T& operator *();
 T* operator ->();

protected:
 void Realease()
 {
  if (--*_refcount == 0)
  {
   _del(_ptr);
   delete _refcount;
  }
 }

 
private:
 T *_ptr;
 Deleter _del;
 long *_refcount;
};

template<class T, class Deleter = Del<T> >
T& Shared_ptr<T,Deleter>::operator *()
{
 return *_ptr;
}

template<class T, class Deleter = Del<T> >
T* Shared_ptr<T, Deleter>::operator ->()
{
 return *_ptr;
}



void test1()
{
 Shared_ptr<int> s1(new int(10));
 //return 0;
 Shared_ptr<int, Free>s2((int*)malloc(sizeof(int)* 10), Free());

// Shared_ptr<int, Free>s2((int*)malloc(sizeof(int)* 10), Free());

 Shared_ptr<FILE, Fclose>s3(fopen("test.txt","w"), Fclose());

}