什么事對(duì)象切片:
目前成都創(chuàng)新互聯(lián)已為近千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬空間、網(wǎng)站托管、服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計(jì)、縉云網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
c++在將一個(gè)派生類轉(zhuǎn)換為基類的過程中,派生類的一部分將被基類接收不到,只能留下基類大小的對(duì)象。
傳值調(diào)用的切片:
#includeusing namespace std; class Base { public: virtual void func1() { cout << "Base::func1" << endl; } virtual void func2() { cout << "Base::func2" << endl; } private: int a; }; class Derive :public Base { public: virtual void func1() { cout << "Derive::func1" << endl; } virtual void func3() { cout << "Derive::func3" << endl; } virtual void func4() { cout << "Derive::func4" << endl; } private: int b; }; typedef void(*FUNC) (); void PrintVTable(int* VTable) { cout << " 虛表地址>" << VTable << endl; for (int i = 0; VTable[i] != 0; ++i) { printf(" 第%d個(gè)虛函數(shù)地址 :0X%x,->", i, VTable[i]); FUNC f = (FUNC)VTable[i]; f(); } cout << endl; } void function(Base b) { b.func1(); } void Test1() { Base b1; Derive d1; int* VTable1 = (int*)(*(int*)&b1); int* VTable2 = (int*)(*(int*)&d1); PrintVTable(VTable1); PrintVTable(VTable2); function(d1); } int main() { Test1(); system("pause"); }
再拷貝的過程中發(fā)生了切片,在調(diào)用構(gòu)造函數(shù)的時(shí)候初始化VPTR指向基類的VTABLE,并且只拷貝了對(duì)象的基類部分,所以最后就變成了一個(gè)基類的對(duì)象。
如果要防止這種現(xiàn)象的發(fā)生,只需把基類定義成純虛函數(shù)就可以了。
將派生類的指針傳遞給基類
#includeusing namespace std; class Base { public: virtual void func1() { cout << "Base::func1" << endl; } virtual void func2() { cout << "Base::func2" << endl; } private: int a; }; class Derive :public Base { public: virtual void func1() { cout << "Derive::func1" << endl; } virtual void func3() { cout << "Derive::func3" << endl; } virtual void func4() { cout << "Derive::func4" << endl; } private: int b; }; typedef void(*FUNC) (); void PrintVTable(int* VTable) { cout << " 虛表地址>" << VTable << endl; for (int i = 0; VTable[i] != 0; ++i) { printf(" 第%d個(gè)虛函數(shù)地址 :0X%x,->", i, VTable[i]); FUNC f = (FUNC)VTable[i]; f(); } cout << endl; } void function(Base* b) { b->func1(); b->func2(); } void Test1() { Base b1; Derive d1; int* VTable1 = (int*)(*(int*)&b1); int* VTable2 = (int*)(*(int*)&d1); PrintVTable(VTable1); PrintVTable(VTable2); function((Base*)&d1); } int main() { Test1(); system("pause"); }
解釋:
在將派生類的指針傳給基類之后,就將派生類的大小看作是積累的大小,所以就只能訪問基類的大小,由于沒有發(fā)生構(gòu)造函數(shù),所以VPTR還是派生類的。