引用计数Reference Count
1. 问题
计数器存放在哪?作为类对象的成员时,遇到拷贝构造时如何处置?
Hasptr p1("Hiya");
Hasptr p2(p1);
Hasptr p3(p1); //p1,p2,p3指向相同的string
2. 解决方法
每个类对象都有一个引用计数,所有类对象的引用计数保证唯一同步。
class Hasptr
{
public:
//2. 当创建一个对象时,只有一个对象共享状态,将此计数器初始化为1。
Hasptr(const std::string &s = std::string()):
ps(new std::string(s),
i(0),
use(new std::size_t(1))) {
}
//3. 拷贝构造函数递增共享的计数器,指出给定对象的状态又被一个新的用户所共享。
Hasptr(const Hasptr &p):ps(p.ps),i(p.i),use(p.use){
++*use};
Hasptr& operator=(const Hasptr&);
~Hasptr();
private:
std::string *ps;
int i;
std::size_t *use;//1. 增加一个引用计数,用来记录有多少对象与正在创建的对象共享状态。
}
2. 1 析构函数
析构函数递减计数器,指出共享状态的用户少了一个,如果计数器为0,则析构函数释放状态。
Hasptr ::~Hasptr()
{
if(--*use == 0){
delete ps;
delete use;
}
}
2. 2 重载赋值
拷贝赋值运算符递增右侧运算对象的计数器,递减左侧运算对象的计数器。如果左侧运算对象的计数器为0,意味着它的共享状态没有用户了,拷贝赋值运算符就必须销毁状态。
Hasptr& Hasptr::operator=(const Hasptr& rhs)
{
++*rhs.use; //递增右侧对象的引用计数
if(--*use == 0) //递减和检测本对象的引用计数
{
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}
3. result
HasPtr h("hi mom!");
HasPtr h2 = h; // no new memory is allocated,
// h and h2 share the same underlying string
HasPtr ret;
ret = h; // HasPtr passed by value, so it is copied
cout << ret.i << "," << *ret.ps << endl;
【参考】