天天看點

string類的寫時拷貝

由于淺拷貝使多個對象共用一塊記憶體位址,調用析構函數時導緻一塊記憶體被多次釋放,導緻程式奔潰。

實作string類的時候通常顯示的定義拷貝構造函數和運算符重載函數。

由于釋放記憶體空間,開辟記憶體空間時花費時間,是以,在我們在不需要寫,隻是讀的時候就可以不用新開辟記憶體空間,就用淺拷貝的方式建立對象,當我們需要寫的時候才去新開辟記憶體空間。這種方法就是寫時拷貝。 

<a href="http://s2.51cto.com/wyfs02/M01/7D/3F/wKioL1bjs57gy9PsAAAHT7mcZX4786.png" target="_blank"></a>

在構造函數中開辟新的空間時多開辟4個位元組的空間,用來存放引用計數器,記錄這快空間的引用次數。

#include&lt;iostream&gt;  

#include&lt;stdlib.h&gt;  

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&amp; str)  

          _str = str._str;  

          ++_GetRefCount();  

     String&amp; operator=(const String&amp; str)  

          if (this != &amp;str)  

               _Release();  

               _str = str._str;  

               ++ _GetRefCount();  

          return *this;  

     char&amp; operator[](int index)//寫時拷貝  

          if (_GetRefCount()&gt;1)//當引用次數大于1時新開辟記憶體空間  

               --_GetRefCount();//原來得空間引用計數器減1  

               char *str = new char[strlen(_str) + 5];  

               strcpy(str+4, _str);  

               _str = str+4;  

               _GetRefCount()++;  

          return _str[index];  

     friend ostream&amp; operator&lt;&lt;(ostream&amp; output, const String&amp; str)  

          output &lt;&lt; str._str;  

          return output;  

private:  

     int&amp; _GetRefCount()  

          return *(int *)(_str - 4);  

     void _Release()  

          if (--_GetRefCount() == 0)  

               delete[] (_str-4);  

     char *_str;  

}; 

==============》

将_pCount與_str所指向的空間放在一起,即隻用new開辟一次空間

string類的寫時拷貝

}

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

繼續閱讀