多型物件模型
1.多型相關概念及使用時需要注意問題。
C++中類的繼承中有多型性的概念,所謂的多型就是在類裡使用虛擬函式後,用父類作為物件指標,來正確的呼叫不同子類或父類來作為相應虛擬函式。虛基類實際就是繼承時使用virtual關鍵字來定義,為的是讓在多重繼承時遇到相同的基類時只保留一份,以確定其使用那個類。
2.多型原理。
當使用基類的指標或引用呼叫重寫的虛擬函式時,當指向父類呼叫的就是父類的虛擬函式,指向子類呼叫的就是子類的虛擬函式
3.什麼是動態聯編,什麼靜態兩邊。
動態聯編 和 靜態聯編 都是多型性的一種體現
聯編是指一個計算機程式自身彼此關聯的過程,在這個聯編過程中,需要確定程式中的操作呼叫(函式呼叫)與執行該操作(函式)的程式碼段之間的對映關係;按照聯編所進行的階段不同,可分為靜態聯編和動態聯編;
靜態聯編:
是指聯編工作是在程式編譯連線階段進行的,這種聯編又稱為早期聯編;因為這種聯編是在程式開始執行之前完成的;
在程式編譯階段進行的這種聯編又稱靜態束定;在編譯時就解決了程式中的操作呼叫與執行該操作程式碼間的關係,確定這種關係又被稱為束定;編譯時束定又稱為靜態束定;
動態聯編:
編譯程式在編譯階段並不能確切地知道將要呼叫的函式,只有在程式執行時才能確定將要呼叫的函式,為此要確切地知道將要呼叫的函式,要求聯編工作在程式執行時進行,這種在程式執行時進行的聯編工作被稱為動態聯編,或動態束定,又叫晚期聯編;C++規定:動態聯編是在虛擬函式的支援下實現的;
4.單繼承/多繼承/菱形繼承/菱形虛擬繼承。多型場景下物件模型
單繼承:當子類與父類構成多型時,子類繼承父類的虛表之後,子類虛表裡虛擬函式在記憶體裡的儲存情況
多繼承:
當一個子類繼承多個父類時構成多繼承,此時子類會繼承這些父類的虛表,子類虛表裡虛擬函式在記憶體裡的儲存情況。
菱形繼承:
class A
{
public:
virtual void f1()
{
cout<<"A::f1()"<<endl;
}
virtual void f2()
{
cout<<"A::f2()"<<endl;
}
public:
int _a;
};
class B:public A
{
public:
virtual void f1()
{
cout<<"B::f1()"<<endl;
}
virtual void f3()
{
cout<<"B::f3()"<<endl;
}
public:
int _b;
};
class C:public A
{
public:
virtual void f1()
{
cout<<"C::f1()"<<endl;
}
virtual void f4()
{
cout<<"C::f4()"<<endl;
}
public:
int _c;
};
class D:public B,public C
{
public:
virtual void f1()
{
cout<<"D::f1()"<<endl;
}
virtual void f5()
{
cout<<"D::f5()"<<endl;
}
public:
int _d;
};
//列印虛擬函式表
typedef void(*V_FUNC)();
void PrintVtable(int* vtable)
{
printf("vtable:%p\n",vtable);
int** pvtable=(int**)vtable;
for(size_t i=0; pvtable[i]!=0;i++)
{
printf("vtable[%u]:0x%p->",i,pvtable[i]);
V_FUNC f=(V_FUNC)pvtable[i];
f();
}
cout<<"------------------------------------\n";
}
void test()
{
D d;
d.B::_a=5;
d.C::_a=6;
d._b=1;
d._c=2;
d._d=3;
PrintVtable(*(int**)&d);
PrintVtable(*(int**)((char*)&d+sizeof(B)));
}
int main()
{
test();
return 0;
}
在普通的菱形繼承中,處於最先的D型別的物件d,它繼承了B,C,並且B,C中分別儲存了一份來自繼承A的變數;除此之外,B,C還存了虛表指標,通過它可以找到虛表中存的虛擬函式地址,最後,d物件還存放了自己定義的變數和繼承B,C自己定義的變數。
菱形虛擬繼承:
菱形虛擬繼承與菱形繼承的區別在於,B,C繼承A的公共成員a,既不儲存在
B裡,也不儲存在C裡,而是儲存在一塊公共的部分,而會將B,C相對於這個變數的偏移地址(這裡的偏移量地址叫做虛基表)存在B,C裡。所以說,物件d裡的B,C裡存放了虛表指標、虛基表指標、自己的變數。