什么事对象切片:

  c++在将一个派生类转换为基类的过程中,派生类的一部分将被基类接收不到,只能留下基类大小的对象。

传值调用的切片:

#include
using 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个虚函数地址 :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");}

  再拷贝的过程中发生了切片,在调用构造函数的时候初始化VPTR指向基类的VTABLE,并且只拷贝了对象的基类部分,所以最后就变成了一个基类的对象。

  如果要防止这种现象的发生,只需把基类定义成纯虚函数就可以了。

将派生类的指针传递给基类

#include
using 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个虚函数地址 :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");}

解释:

   在将派生类的指针传给基类之后,就将派生类的大小看作是积累的大小,所以就只能访问基类的大小,由于没有发生构造函数,所以VPTR还是派生类的。