C++/CLI思辨錄之拷貝建構函式

來源:互聯網
上載者:User

     雖然對象複製看上去很簡單,然而如果你沒有對其正確理解,可能會出現一些嚴重問題。預設情況下,複製對象會導致相應的所有成員的複製。如果你只有執行個體成員,這看上去是相當不錯的。但是如果你的類中含有指向在堆中分配的對象時,情況會怎樣呢?考慮下面的代碼片斷:

#include <stdio.h>
#include <string.h>
class Person
{
 private:
  char* _name;
 public:
  Person()
  {
   _name = new char[256];
  }
  void SetName(const char* name)
  {
   if(strlen(name) + 1 < 256)
    strcpy(_name,name);
  }
  void PrintName()
  {
   printf("%s\n",_name);
  }
 };
 int main()
 {
  // 建立對象的第一個執行個體並賦於名字為John
  Person p1;
  p1.SetName("John");
  p1.PrintName();
  //通過複製p1引用的對象建立另一個對象
  Person p2(p1);
  p2.SetName("Alice");
  p2.PrintName();
  //現在再輸出p1的名字
  p1.PrintName();
  scanf("q");
  return 0;
 }

  這裡的類Person有一個指向在堆上分配的字元數組的指標。當構造Person對象時,它建立該字元數組並把它的位置存放到變數_name中。

  但是當你建立Person 對象 p2 時,p2的成員用p1的成員初始化。因而,p1的 _name與p2的 _name指向相同的堆對象。如在上例中看到的,調用p2.SetName將改變由這兩個類共用的值。所以,當第二次調用p1.PrintName,列印結果是"Alice"。

  所以,這不是我們複製對象所期望的結果,而且還會導致堆崩潰的問題。請再考慮某個函數刪除了該數組而p1又要調用該函數的情況?下面,當p2調用PrintName時,它將盡量存取實際上不是在堆上的對象。這種情況下產生的結果往往是難以預料的。

  C++允許我們通過定義拷貝建構函式來克服這類問題。在我們每次通過複製另一個對象來初始化一個對象時,拷貝建構函式都被執行。你可以在拷貝建構函式中覆蓋掉預設的成員函數的複製行為。

  所以,我們的類Person應該修改如下:

class Person
{
 private:
  char* _name;
 public:
  Person()
  {
   _name = new char[256];
  }
  // 這是拷貝建構函式。在此我們初始化一個新的數組,為Person的執行個體所用
  Person(Person&)
  {
   _name = new char[256];
  }
  void SetName(const char* name)
  {
   if(strlen(name) + 1 < 256)
    strcpy(_name,name);
  }
  void PrintName()
  {
   printf("%s\n",_name);
  }
};

  這裡類Person中的拷貝建構函式保證了它初始化一個新的數組,為在複製時產生的每一個對象執行個體所用。這就避免了前面我們提到的問題。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.