一、寫時拷貝的引入
class String
{
friend ostream& operator<<(ostream& os,const String& s);
public:
String(const char* s)
:_str(new char[strlen(s)+1])
{
strcpy(_str,s);
}
//深拷貝
String(String& s) //拷貝構造
:_str(new char[strlen(s)+1])
{
strcpy(_str,s._str);
}
private:
char* _str;
};
void test1()
{
String str1("abcde");
String str2(str1);
cout<這個String類中只簡單實現了構造函數和拷貝構造函數,很明顯可以看出,在創建str1和str2時都開辟了空間。但是對於str2,只是單純的使用了它並將str2所指向的內容輸出,並沒有操作這塊空間,因此給str2開辟空間會顯得有點浪費。這時就可以引用寫時拷貝的方式。
二、什麼是寫時拷貝?
顧名思義,寫時拷貝就是在需要修改這塊空間的內容時才分配一塊空間。同樣用上邊的例子,寫時拷貝會存在一個計數器,並且多個對象指向同一塊空間,每次創建一個新的對象時,計數器++,銷毀時計數器 - - (具體代碼如下:)

實現一:
//計數器
class String
{
friend ostream& operator<<(ostream& os,const String& s);
public:
String(const char* s = "")
:_str(new char[strlen(s)+1])
,_pCount(new int(1))
{
cout<<"gouzao"<void test()
{
String str1("abcde");
String str2(str1);
String str3;
str3 = str2;
cout<實現二:
將_pCount與_str所指向的空間放在一起,即只用new開辟一次空間
class String
{
friend ostream& operator<<(ostream& os,String& s);
public:
String(const char*str = "")
:_str(new char[strlen(str)+1+4])
{
*(int *)_str = 1; //*_pCount = 1
_str = _str+4; //找到數據存放的位置
strcpy(_str,str);
GetCount() = 1;
}
String(const String& str)
:_str(str._str)
{
++GetCount();
}
~String()
{
if(--GetCount() == 0)
{
delete[] (_str-4);
}
}
String& operator=(const String& s)
{
if (this != &s)
{
if (--GetCount() == 0)
{
delete[] (_str-4);
}
++GetCount();
_str = s._str;
}
return *this;
}
private:
int& GetCount() //獲得_pCount
{
return *((int *)_str-1);
}
private:
char *_str;
};
ostream& operator<<(ostream& os,String& s)
{
os<void test1()
{
String str1("abcde");
String str2(str1);
String str3;
str3 = str2;
cout<