C++中的写时拷贝

一、什么是写时拷贝?

就是当你在读取一片空间时,系统并不会为你开辟一个一模一样的空间给你;只有在当你真正修改的时候,才会开辟一片空间给你。

二、怎么实现写时拷贝呢?

(1)、使用引用计数来实现。所以我们在分配空间时需要多分配4个字节,来记录有多少个指针指向这个空间。

(2)、有新的指针指向这篇空间时,那么引用计数就加一;当有一个指针要释放该空间时,那么引用计数就减一。

(3)、当有指针要修改这片空间时,则为该指针重新分配自己的空间,原空间的引用计数减一,新空间的引用计数加一。

三、自己实现一个string类

#include<iostream>
#include<string>
using namespace std;

class CString
{
public:
	CString(char* ptr=NULL):mptr(new char[strlen(ptr)+1+4])
	{
		mptr+=4;
		strcpy(mptr,ptr);//前4个字节用来存放引用计数
		getRefCount(mptr)=1;//引用计数的初始值设为1
	}
	CString(const CString& rhs):mptr(rhs.mptr)
	{
		++getRefCount(mptr);
	}
	CString& operator=(const CString &rhs)
	{
		if(this != &rhs)
		{
			Release(mptr);
			mptr=rhs.mptr;
			getRefCount(mptr);
		}
		return *this;
	}
	char& operator[](int index)
	{
		if(getRefCount(mptr)>1)
		{
			char *ptr=mptr;
			mptr=new char(strlen(mptr)+5);
			--getRefCount(ptr);
			mptr+=4;
			strcpy(mptr,ptr);
			getRefCount(mptr)=1;
		}
		return mptr[index];
	}
	~CString(){	}
	void Print()
	{
		cout<<mptr<<endl;
	}
private:
	char* mptr;
	int& getRefCount(char* ptr)
	{
		return *(int*)(ptr-4);
	}
	void Release(char* ptr)
	{
		if (--getRefCount(mptr) == 0)
		{
			delete[] (mptr - 4);//释放的时候还有存放引用计数的四个字节
		}
	}
};
int main()
{
	CString str1("hello");//构造函数
	CString str2(str1);//拷贝构造函数
	CString str3("world");//构造函数
	str1=str3;
	str1[0]='a';
	str1.Print();
	str2.Print();
	str3.Print();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zhuoya_/article/details/80636029