由于淺拷貝使多個對象共用一塊記憶體位址,調用析構函數時導緻一塊記憶體被多次釋放,導緻程式奔潰。
實作string類的時候通常顯示的定義拷貝構造函數和運算符重載函數。
由于釋放記憶體空間,開辟記憶體空間時花費時間,是以,在我們在不需要寫,隻是讀的時候就可以不用新開辟記憶體空間,就用淺拷貝的方式建立對象,當我們需要寫的時候才去新開辟記憶體空間。這種方法就是寫時拷貝。
<a href="http://s2.51cto.com/wyfs02/M01/7D/3F/wKioL1bjs57gy9PsAAAHT7mcZX4786.png" target="_blank"></a>
在構造函數中開辟新的空間時多開辟4個位元組的空間,用來存放引用計數器,記錄這快空間的引用次數。
#include<iostream>
#include<stdlib.h>
using namespace std;
class String
{
public:
String(char *str = "")
:_str(new char[strlen(str) + 5])
{
*(int *)_str = 1;
_str += 4;
strcpy(_str, str);
}
~String()
if (_str != NULL)
{
_Release();
}
String(const String& str)
_str = str._str;
++_GetRefCount();
String& operator=(const String& str)
if (this != &str)
_Release();
_str = str._str;
++ _GetRefCount();
return *this;
char& operator[](int index)//寫時拷貝
if (_GetRefCount()>1)//當引用次數大于1時新開辟記憶體空間
--_GetRefCount();//原來得空間引用計數器減1
char *str = new char[strlen(_str) + 5];
strcpy(str+4, _str);
_str = str+4;
_GetRefCount()++;
return _str[index];
friend ostream& operator<<(ostream& output, const String& str)
output << str._str;
return output;
private:
int& _GetRefCount()
return *(int *)(_str - 4);
void _Release()
if (--_GetRefCount() == 0)
delete[] (_str-4);
char *_str;
};
==============》
将_pCount與_str所指向的空間放在一起,即隻用new開辟一次空間

}
本文轉自莫水千流部落格園部落格,原文連結:http://www.cnblogs.com/zhoug2020/p/6542467.html,如需轉載請自行聯系原作者