1. 程式人生 > >虛函數中的繼承關系

虛函數中的繼承關系

虛函數 父類 子類 繼承 靜態 動態

1.當一個類繼承另一個類時。如果父類中有虛函數時。倆個類都有自己的函數數組(虛函數表)子類中的函數數組成員是拷貝父類中的。如果。子類重寫父類中的虛函數時。會把重寫的虛函數地址。覆蓋對應的那個函數數組成員。
2.父類有幾個虛表(函數數組)子類也就對應的有自己的虛表。表是各有的不是共享的。但不保證內容一定不同。內容可以相同。
3.子類繼承父類。如果子類中有自己獨有的虛函數。同時繼承了父類的虛表(也就是父類中也有虛函數)。他會把自己獨有的虛函數地址。放到從繼承順序的第一個表中。如:
`
#include<iostream>
#include<string>
using namespace std;
class bassA{
virtual void fun1(){
cout<<"fun1"<<endl;
}
};
class bassB{
virtual void fun2(){
cout<<"fun2"<<endl;
}
};
class bassC{
public:
void funC(){
cout<<"funC"<<endl;
}
};
class sun :public bassA,public bassB//只有倆個虛表
{

virtual void fun3(){  //這個函數地址放在bassA虛表中。不會生成一個新的虛表(函數數組)(按虛表順序)
    cout<<"sun"<<endl;
}

};
class sun2 :public bassA,public bassB
{

virtual void fun1(){  //這個函數地址 覆蓋bassA中的fun1的地址也就是改變函數數組中成員的值。
    cout<<"sun2"<<endl;
}

};
class sun3 :public bassC,public bassB
{
public:
virtual void funC(){
cout<<"sun3"<<endl;
}
};
int main(){
sun3 psun;
bassC bac;
psun=(sun3
)&bac;

psun->funC();//這裏會報錯bassC類中funC不是虛函數
}

父類指針與子類指針的問題
1.第一步先看動態還是靜態聯編。
2.如果是靜態聯編不管你的指針指向誰。它只看指針類型(對象)。什麽類型就調用那個類型的函數。
3.動態聯編(條件必須是指針。必須是虛函數) 先看你指針類型(對象)的函數是否為虛函數。如果是。它會調用你實際指向的類型(對象)的函數。這裏還沒有結束。最後會看你的指針指向類型(對象)的函數是否為虛函數。是調用。不是報錯。

虛函數中的繼承關系