posts - 134,comments - 22,trackbacks - 0
          一 default memberwise initialization
             通常我們都會為非抽象類定義拷貝構造函數,如果沒有定義時,我們以class的一個object作為另一個object的初值時,編譯器內部以default memberwise initialization 方式完成,對于member class object 則不會拷貝,而是遞歸調用 memberwise initialization。
             copy constructor和default constructor一樣,在必要的時候才由編譯器產生出來。copy constructor 以初始化的方式復制object,另一種是指定值(assignment),通過copy assignment operator

          二 bitwise copy semantics
             編譯器是否合成出考構是看class是否展現了 bitwise copy semantics,

          // declaration exhibits bitwise copy semantics
          class Word {
          public:
             Word( const char* );
             ~Word() { delete [] str; }
             // ...
          private:
             int cnt;
             char *str;
          };

          如書中所說,這個展現了bitwise copy semantics,why?

          // declaration does not exhibits bitwise copy semantics
          class Word {
          public:
             Word( const String& );
             ~Word();
             // ...
          private:
             int cnt;
             String str;
          };

          這個沒有展現,同樣不明白。。。。。。。
          對于后者,編譯器就會合成出一個 copy constructor。

          那么什么時候不展現bitwise copy semantics呢,分為四種情況
          (1)class 內含一個member object ,后者聲明有一個copy constructor,無論是程序員聲明的,還是被編譯器合成的。
          (2)class 繼承自的基類有一個copy constructor,無論程序員聲明的,還是被編譯器合成的。
             對于這2種情況,編譯器必須將memb或base class的copy constru調用操作安插到被合成的copy constr中。
          (3)class聲明了一個或多個 virtual function時
          (4)class派生的基類串中至少有一個virtual base class時。

             情況3中,類中會額外增加vptr和vbtl,故就不在展現bitwise seamantics了,編譯器需要合成出一個copy constructor,以將vptr適當初始化。
             同類型的對象vptr指向的相同的vtbl,基類和派生類的不同,看一段程序

          class b{
          public:
              int i;
              virtual void f(){}
          };
          class d:public b{
          public:
              int ii;
          };

          int main(void) {
              b bbb;
              d dob;
              d bob;
              cout<<&bbb<<" "<<&bbb.i<<" "<<endl;
              cout<<&dob<<" "<<&dob.i<<" "<<&dob.ii<<endl;
              cout<<&bob<<" "<<&bob.i<<" "<<&bob.ii<<endl;
              int *p=(int *)&bbb;
              int *p2=(int *)&dob;
              int *p3=(int *)&bob;
              cout<<"bbb vptr ->"<<*p<<endl;
              cout<<"dob vptr ->"<<*p2<<endl;
              cout<<"bob vptr ->"<<*p3<<endl;

              b bb2=dob;
              cout<<&bb2<<" "<<&bb2.i<<" "<<endl;
              int *p4=(int *)&bb2;
              cout<<"bb2 vptr ->"<<*p4<<endl;
              puts("end in main");
              return EXIT_SUCCESS;
          }

          輸出:

          0x22ff78 0x22ff7c
          0x22ff68 0x22ff6c 0x22ff70
          0x22ff58 0x22ff5c 0x22ff60
          bbb vptr ->4409528
          dob vptr ->4409544
          bob vptr ->4409544
          12 12
          0x22ff48 0x22ff4c
          bb2 vptr ->4409528
          end in main

          b bb2=dob; 語句處,發生了派生類對象的切割,其vptr指向了基類的vbtl,而不是派生類。

          參考文章:
          轉-復制概念相關,深拷貝與淺拷貝
          posted on 2009-12-10 15:35 何克勤 閱讀(233) 評論(0)  編輯  收藏 所屬分類: C/C++
          主站蜘蛛池模板: 蓬莱市| 仁怀市| 印江| 和林格尔县| 莱阳市| 监利县| 赤水市| 桐庐县| 土默特左旗| 安仁县| 吴桥县| 安达市| 河东区| 长葛市| 海晏县| 开原市| 都昌县| 灌云县| 思茅市| 靖州| 师宗县| 佳木斯市| 天台县| 平度市| 张家口市| 大渡口区| 翁源县| 崇礼县| 毕节市| 新龙县| 阿勒泰市| 克什克腾旗| 霍州市| 洪洞县| 新田县| 贺州市| 岳池县| 海门市| 诏安县| 云阳县| 恩平市|