string类写时拷贝

一种通过创建临时空间解决写时拷贝问题的方法

指路:模拟实现string类。地址:https://blog.csdn.net/MPF1230/article/details/104059562

源代码获取:
https://github.com/akh5/C-/blob/master/STL/copyOnWrite.cpp

由于浅拷贝多个对象共用一个资源,导致其中一个对象修改其内容时,会导致其他对象也会进行相应修改。
在这里插入图片描述
    如果当前s1对象将 s1[0] 元素改为“A”,则s2,s3的0号元素也将改为"A"

为了解决这种问题,我们需要新建一个临时资源,将s1指向一个临时资源,在临时资源内修改,s1就与s2,s3独立开来。
在这里插入图片描述

namespace my
{
	class string
	{
	public:
		string(char* str = "")
			:_pCount(new int(1))
		{
			if (nullptr == str)
				str = "";

			//申请空间
			_str = new char[strlen(str) + 1]; //“\0”
			strcpy(_str, str);
		}

		//浅拷贝
		string(const string& s)
			:_str(s._str)
			, _pCount(s._pCount)
		{
			++*_pCount;
		}

		string &operator=(const string& s)
		{
			if (this != &s)
			{
				//需要将当前对象的旧资源释放掉
				if (0 == --*_pCount)
				{
					delete[] _str;
					delete _pCount;
				}
				_str = s._str;
				_pCount = s._pCount;
				(*_pCount)++;
			}
			return *this;
		}
		~string()
		{
			if (_str && --*_pCount == 0)
			{
				delete[] _str;
				_str = nullptr;

				delete _pCount;
				_pCount = nullptr;
			}
		}

		char& operator[](size_t index)
		{
			if (GetRef() > 1)
			{
				string strtemp(_str);
				this->swap(strtemp);
			}
			return _str[index];
		}
		
		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_pCount, s._pCount);
		}

	private:
		int GetRef()
		{
			return *_pCount;
		}
		char* _str;
		int* _pCount;
	};
}

关于解决写实拷贝问题,集中体现在[]运算符的重载函数中

char& operator[](size_t index)
		{
			if (GetRef() > 1)
			{
				string strtemp(_str);
				this->swap(strtemp);
			}
			return _str[index];
		}

先判断当前资源的引用量是否大于1,大于1时说明已经有多个对象使用当前资源,所以调用自身的拷贝构造,构造一个临时的作用域strtemp,并使用this指针将两者内容交换,一旦出了if函数的作用域,strtemp会自动调用析构函数,销毁自己,并将资源计数器减1。

在这里插入图片描述
一开始,s1,s2,s3的地址都是相同的,
在这里插入图片描述
对s1[0]进行修改,s1的指针与临时空间交换,所以s1的地址与s2,s3不同,s1修改了A,s2,s3与先前一样

发布了52 篇原创文章 · 获赞 13 · 访问量 5436

猜你喜欢

转载自blog.csdn.net/MPF1230/article/details/104126302