C++/引用计数器和写实拷贝

对类的拷贝分为深拷贝和浅拷贝,深拷贝是新开辟一个空间存放数据,而浅拷贝是共享一个空间存放数据。浅拷贝更节省空间,而深拷贝的可靠性高,安全性高。为了解决浅拷贝的安全问题,我们使用引用计数器的方法。

引用计数器:

定义String_rep类,将String类设置为友元类,方便String类操作其私有成员

私有成员变量:字符指针m_data存放数据,use_count用来计数

class String_rep
{
	friend class String;
public:
	String_rep(const char* str = "")
	{
		m_data = new char[strlen(str) + 1];
		strcpy(m_data, str);
		increment();
	}
	~String_rep()
	{
		delete[]m_data;
		m_data = NULL;
	}

	void increment()
	{
		use_count++;
	}

	void decrement()
	{
		if (--use_count == 0)
		{
			delete this;
		}
	}

private:
	char* m_data;
	int use_count;
};

成员函数increment()和decrement()用来改变计数

构造函数:用字符串初始化构造,开辟空间,并将字符串拷贝至空间,调用increment()引用计数器计数+1

析构函数:当引用计数器为零的时候调用析构函数释放空间

String类:

class String
{
	friend ostream& operator<<(ostream& out,const String &s);
public:
	String(const char* str = "")
	{
		rep = new String_rep(str);
	}
	String(const String& s)
	{
		rep = s.rep;
		rep->increment();
	}
	String& operator=(String& s)
	{
		rep->decrement();
		rep = s.rep;
		rep->increment();
		return *this;
	}
	~String()
	{
		rep->decrement();
	}
	void to_upper()
	{
		//写实拷贝
		if (rep->use_count > 1)
		{
			String_rep* new_rep = new String_rep(rep->m_data);
			rep->decrement();
			rep = new_rep;
			rep->increment();
		}

		char* ch = rep->m_data;
		while( *ch != '\0')
		{
			if (*ch >= 'a' && *ch <= 'z')
			{
				*ch -= 32;
				ch++;
			}
		}
	}
private:
	String_rep* rep;
};

String类用字符串构造函数,创建一个自己的引用计数器,当有对象拷贝构造时,对象的引用计数器指向被拷贝的引用计数器rep,并使引用计数器+1,若是赋值函数则当前引用计数器-1并使指向拷贝的引用计数器同时引用计数器+1

写实拷贝:

如例子,我们想将对象的m_data的小写改为大写,但是因为我们使浅拷贝,使用的是共同的空间,如果改变一个对象的m_data就会改变全部对象的m_data,为了防止这种情况发生,我们使用写实拷贝计数:

如果引用计数器为1,则说明只有1个对象,没有对象拷贝构造,直接更改

若大于1,则创建新的引用计数器,将当前的引用计数器减1,并指向新的计数器,新的计数器+1

	void to_upper()
	{
		//写实拷贝
		if (rep->use_count > 1)
		{
			String_rep* new_rep = new String_rep(rep->m_data);
			rep->decrement();
			rep = new_rep;
			rep->increment();
		}

		char* ch = rep->m_data;
		while( *ch != '\0')
		{
			if (*ch >= 'a' && *ch <= 'z')
			{
				*ch -= 32;
				ch++;
			}
		}
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值