條款十一: 為需要動態分配記憶體的類聲明一個拷貝建構函式和一個拷貝賦值運算子

來源:互聯網
上載者:User

標籤:style   blog   color   資料   ar   問題   div   工作   

看下面一個表示string對象的類:

// 一個很簡單的string類class string {public:  string(const char *value);  ~string();  ...                           // 沒有拷貝建構函式和operator=private:  char *data;};string::string(const char *value){  if (value) {    data = new char[strlen(value) + 1];    strcpy(data, value);  }  else {    data = new char[1];    *data = ‘\0‘;  }}inline string::~string() { delete [] data; }

請注意這個類裡沒有聲明賦值操作符和拷貝建構函式。這會帶來一些不良後果。

如果這樣定義兩個對象:

string a("hello"); string b("world");

其結果就會如下所示:

a:  data——> "hello\0"

b:  data——> "world\0"

對象a的內部是一個指向包含字串"hello"的記憶體的指標,對象b的內部是一個指向包含字串"world"的記憶體的指標。如果進行下面的賦值:

b = a;

因為沒有自訂的operator=可以調用,c++會產生並調用一個預設的operator=操作符(見條款45)。這個預設的賦值操作符會執行從a的成員到b的成員的逐個成員的賦值操作

這種情況下至少有兩個問題。第一,b曾指向的記憶體永遠不會被刪除,因而會永遠丟失。這是產生記憶體流失的典型例子。第二,現在a和b包含的指標指向同一個字串,那麼只要其中一個離開了它的生存空間,其解構函式就會刪除掉另一個指標還指向的那塊記憶體。

拷貝建構函式的情況和賦值操作符還有點不同。在傳值調用的時候,它會產生問題。當然正如條款22所說明的,一般很少對對象進行傳值調用,但還是看看下面的例子:

void donothing(string localstring) {}string s = "the truth is out there";donothing(s);

因為被傳遞的localstring是一個值,它必須從s通過(預設)拷貝建構函式進行初始化。於是localstring擁有了一個s內的指標的拷貝。當donothing結束運行時,localstring離開了其生存空間,調用解構函式。其結果也將是:s包含一個指向localstring早已刪除的記憶體的指標。

用delete去刪除一個已經被刪除的指標,其結果是不可預測的。

解決這類指標混亂問題的方案在於,只要類裡有指標時,就要寫自己版本的拷貝建構函式和賦值操作符函數。在這些函數裡,你可以拷貝那些被指向的資料結構,從而使每個對象都有自己的拷貝(深拷貝);或者你可以採用某種引用計數機制(見條款 m29)去跟蹤當前有多少個對象指向某個資料結構。引用計數的方法更複雜,而且它要求建構函式和解構函式內部做更多的工作,但在某些(雖然不是所有)程式裡,它會大量節省記憶體並切實提高速度。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.