一、什么是写时拷贝?
就是当你在读取一片空间时,系统并不会为你开辟一个一模一样的空间给你;只有在当你真正修改的时候,才会开辟一片空间给你。
二、怎么实现写时拷贝呢?
(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;
}