一 default memberwise initialization
通常我們都會(huì)為非抽象類定義拷貝構(gòu)造函數(shù),如果沒(méi)有定義時(shí),我們以class的一個(gè)object作為另一個(gè)object的初值時(shí),編譯器內(nèi)部以default memberwise initialization 方式完成,對(duì)于member class object 則不會(huì)拷貝,而是遞歸調(diào)用 memberwise initialization。
copy constructor和default constructor一樣,在必要的時(shí)候才由編譯器產(chǎn)生出來(lái)。copy constructor 以初始化的方式復(fù)制object,另一種是指定值(assignment),通過(guò)copy assignment operator
二 bitwise copy semantics
編譯器是否合成出考構(gòu)是看class是否展現(xiàn)了 bitwise copy semantics,
// declaration exhibits bitwise copy semantics
class Word {
public:
Word( const char* );
~Word() { delete [] str; }
// ...
private:
int cnt;
char *str;
};
|
如書中所說(shuō),這個(gè)展現(xiàn)了bitwise copy semantics,
why?
// declaration does not exhibits bitwise copy semantics
class Word {
public:
Word( const String& );
~Word();
// ...
private:
int cnt;
String str;
};
|
這個(gè)沒(méi)有展現(xiàn),同樣不明白。。。。。。。
對(duì)于后者,編譯器就會(huì)合成出一個(gè) copy constructor。
那么什么時(shí)候不展現(xiàn)bitwise copy semantics呢,分為四種情況
(1)class 內(nèi)含一個(gè)member object ,后者聲明有一個(gè)copy constructor,無(wú)論是程序員聲明的,還是被編譯器合成的。
(2)class 繼承自的基類有一個(gè)copy constructor,無(wú)論程序員聲明的,還是被編譯器合成的。
對(duì)于這2種情況,編譯器必須將memb或base class的copy constru調(diào)用操作安插到被合成的copy constr中。
(3)class聲明了一個(gè)或多個(gè) virtual function時(shí)
(4)class派生的基類串中至少有一個(gè)virtual base class時(shí)。
情況3中,類中會(huì)額外增加vptr和vbtl,故就不在展現(xiàn)bitwise seamantics了,編譯器需要合成出一個(gè)copy constructor,以將vptr適當(dāng)初始化。
同類型的對(duì)象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; 語(yǔ)句處,發(fā)生了派生類對(duì)象的切割,其vptr指向了基類的vbtl,而不是派生類。
參考文章:
轉(zhuǎn)-復(fù)制概念相關(guān),深拷貝與淺拷貝
posted on 2009-12-10 15:35
何克勤 閱讀(227)
評(píng)論(0) 編輯 收藏 所屬分類:
C/C++