• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • C++/CLI思辨錄之拷貝構造函數

    發表于:2007-05-25來源:作者:點擊數: 標簽:思辨錄之C++拷貝CLI
    雖然對象復制看上去很簡單,然而如果你沒有對其正確理解,可能會出現一些嚴重問題。默認情況下,復制對象會導致相應的所有成員的復制。如果你只有實例成員,這看上去是相當不錯的。但是如果你的類中含有指向在堆中分配的對象時,情況會怎樣呢?考慮下面的代
     雖然對象復制看上去很簡單,然而如果你沒有對其正確理解,可能會出現一些嚴重問題。默認情況下,復制對象會導致相應的所有成員的復制。如果你只有實例成員,這看上去是相當不錯的。但是如果你的類中含有指向在堆中分配的對象時,情況會怎樣呢?考慮下面的代碼片斷:

    clearcase/" target="_blank" >cc66" width="90%" align="center" bgcolor="#e3e3e3" border="1">
    #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&amp;)
      {
       _name = new char[256];
      }
      void SetName(const char* name)
      {
       if(strlen(name) + 1 < 256)
        strcpy(_name,name);
      }
      void PrintName()
      {
       printf("%s\n",_name);
      }
    };

      這里類Person中的拷貝構造函數保證了它初始化一個新的數組,為在復制時產生的每一個對象實例所用。這就避免了前面我們提到的問題。

      希望上面所述能夠幫助讀者理解拷貝構造函數及其使用場所。

    原文轉自:http://www.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>