在基類中定義了public虛函數,在派生類中将其重寫,但是設定為private,為什麼通過基類指針仍然可以發生動态綁定調用派生類中的private虛函數?
例子如下:
class Base
{
public:
// public虛函數
virtual void Disp() { cout << "base.\n"; }
};
class Derived : public Base
{
private:
// 重寫基類虛函數,但是放在private中
virtual void Disp() { cout << "derived.\n"; }
};
void main()
{
Derived Dobj;
Base *pBase = &Dobj;
pBase->Disp(); // 顯示的結果是派生類的虛函數被調用!
}
正确的解釋:派生類中虛函數的通路權限是在編譯階段由基類确定的,在運作階段不再檢查通路權限,是以,虛函數的通路權限與派生類就沒關系了。
更進一步的解釋:當pBase->Disp()時,首先通過這個對象的vptr找到對應的vtable, 因為它實際上是Derived對象,是以找到的是Derived的虛表,所有的Derived對象都共用這個虛表。又因為是通過基類的指針調用的,編譯器從Base的類型資訊中查到Disp是虛表中的第一個entry, 而且這個函數的通路權限是public的,是以首先它讓你調用,其次,從虛表第一個entry中取出的函數位址對應着Derived::Disp, 是以最後是Derived::Disp被調用,Derived::Disp在Derived中的通路權限在這裡是無關的了,編譯器根本不會費事去查詢這一資訊。甚至這一資訊可能根本編譯器也不知道。