智能指针类的使用与测试
  至此,我们的智能指针类完成了,我们可以来看看如何使用
int main()
{
//定义一个基础对象类指针
Point *pa = new Point(10, 20);
//定义三个智能指针类对象,对象都指向基础类对象pa
//使用花括号控制三个指针指针的生命期,观察计数的变化
{
SmartPtr sptr1(pa);//此时计数count=1
{
SmartPtr sptr2(sptr1); //调用复制构造函数,此时计数为count=2
{
SmartPtr sptr3=sptr1; //调用赋值操作符,此时计数为conut=3
}
//此时count=2
}
//此时count=1;
}
//此时count=0;pa对象被delete掉
cout << pa->getX ()<< endl;
system("pause");
return 0;
}
  来看看运行结果咯:
  还有2个指针指向基础对象
  还有1个指针指向基础对象
  -17891602
  请按任意键继续. . .
  如期,在离开大括号后,共享基础对象的指针从3->2->1->0变换,后计数为0时,pa对象被delete,此时使用getX()已经获取不到原来的值。
  智能指针类的改进一
  虽然我们的SmartPtr类称为智能指针,但它目前并不能像真正的指针那样有->、*等操作符,为了使它看起来更像一个指针,我们来为它重载这些操作符。代码如下所示:
{
public:
SmartPtr(Point *ptr) :rp(new RefPtr(ptr)) { }
SmartPtr(const SmartPtr &sp) :rp(sp.rp) { ++rp->count; }
SmartPtr& operator=(const SmartPtr& rhs) {
++rhs.rp->count;
if (--rp->count == 0)
delete rp;
rp = rhs.rp;
return *this;
}
~SmartPtr() {
if (--rp->count == 0)
delete rp;
else
cout << "还有" << rp->count << "个指针指向基础对象" << endl;
}
Point & operator *()        //重载*操作符
{
return *(rp->p);
}
Point* operator ->()       //重载->操作符
{
return rp->p;
}
private:
RefPtr *rp;
};
  然后我们可以像指针般使用智能指针类
  Point *pa = new Point(10, 20);
  SmartPtr sptr1(pa);
  //像指针般使用
  cout<<sptr1->getX();
  智能指针改进二
  目前这个智能指针智能用于管理Point类的基础对象,如果此时定义了个矩阵的基础对象类,那不是还得重新写一个属于矩阵类的智能指针类吗?但是矩阵类的智能指针类设计思想和Point类一样啊,不能借用吗?答案当然是能,那是使用模板技术。为了使我们的智能指针适用于更多的基础对象类,我们有必要把智能指针类通过模板来实现。这里贴上上面的智能指针类的模板版:
//模板类作为友元时要先有声明
template <typename T>
class SmartPtr;
template <typename T>
class U_Ptr     //辅助类
{
private:
//该类成员访问权限全部为private,因为不想让用户直接使用该类
friend class SmartPtr<T>;      //定义智能指针类为友元,因为智能指针类需要直接操纵辅助类
//构造函数的参数为基础对象的指针
U_Ptr(T *ptr) :p(ptr), count(1) { }
//析构函数
~U_Ptr() { delete p; }
//引用计数
int count;
//基础对象指针
T *p;
};
template <typename T>
class SmartPtr   //智能指针类
{
public:
SmartPtr(T *ptr) :rp(new U_Ptr<T>(ptr)) { }      //构造函数
SmartPtr(const SmartPtr<T> &sp) :rp(sp.rp) { ++rp->count; }  //复制构造函数
SmartPtr& operator=(const SmartPtr<T>& rhs) {    //重载赋值操作符
++rhs.rp->count;     //首先将右操作数引用计数加1,
if (--rp->count == 0)     //然后将引用计数减1,可以应对自赋值
delete rp;
rp = rhs.rp;
return *this;
}
T & operator *()        //重载*操作符
{
return *(rp->p);
}
T* operator ->()       //重载->操作符
{
return rp->p;
}
~SmartPtr() {        //析构函数
if (--rp->count == 0)    //当引用计数减为0时,删除辅助类对象指针,从而删除基础对象
delete rp;
else
cout << "还有" << rp->count << "个指针指向基础对象" << endl;
}
private:
U_Ptr<T> *rp;  //辅助类对象指针
};
  好啦,现在我们能够使用这个智能指针类对象来共享其他类型的基础对象啦,比如int:
int main()
{
int *i = new int(2);
{
SmartPtr<int> ptr1(i);
{
SmartPtr<int> ptr2(ptr1);
{
SmartPtr<int> ptr3 = ptr2;
cout << *ptr1 << endl;
*ptr1 = 20;
cout << *ptr2 << endl;
}
}
}
system("pause");
return 0;
}
  运行结果如期所愿,SmartPtr类管理起int类型来了:
  2
  20
  还有2个指针指向基础对象
  还有1个指针指向基础对象
  请按任意键继续. . .