C++ Primer 5th笔记(chap 13 拷贝控制)引用计数

引用计数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;

在这里插入图片描述


【参考】

[1] 代码referenceCount.h

猜你喜欢

转载自blog.csdn.net/thefist11cc/article/details/113858495