使用一个辅助类,成员函数全部私有,对智能指针类友元,只有智能指针类可以对其操作,辅助类含有两个数据成员:计数count与基础对象指针(模板)
智能指针类用引用计数来实现,将一个计数器与类指向的对象相关联,引用计数跟踪共有多少个类对象共享同一指针。具体做法如下:
- 当创建类的新对象时,初始化指针,并将引用计数设置为1
- 当对象作为另一个对象的副本时,复制构造函数复制副本指针,并增加与指针相应的引用技术(加1)
- 使用赋值操作符对一个对象进行赋值时,先使左操作数的指针的引用计数减1(因为指针已经指向别的地方),如果减1后引用计数为0,则释放指针所指对象内存,然后增加右操作数所指对象的引用计数(因为此时做操作数指向对象即右操作数指向对象)
- 析构函数:调用析构函数时,析构函数先使引用计数减1 ,如果减至0则delete对象。
#pragma once
#include "common.h"
template <typename T>
class SmartPtr;
template <typename T>
//基础对象类
class Point
{
public:
Point(int xVal = 0, int yVal = 0) :x(xVal), y(yVal) { }
int getX() const { return x; }
int getY() const { return y; }
void setX(int xVal) { x = xVal; }
void setY(int yVal) { y = yVal; }
private:
int x, y;
};
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* 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");
结果: