在討論虛函式之前,首先看一下類中同名函式的問題多重繼承,最常見的問題就是繼承的成員同名而產生的二義性(ambiguous)問題。
會出現如下幾種情況:
#include
using
namespace
std;
class a
};class b
};class c : public a, public b;
int main()
後果:無法確定需要訪問哪乙個基類的成員,編譯出錯
> cl /ehsc x.cpp
x.cpp
x.cpp(24) : error c2385: 對「a」的訪問不明確
可能是「a」(位於基「a」中)
也可能是「a」(位於基「b」中)
解決辦法是使用基類名限定,修改為
cl.a
::a=3;
//表示是派生類物件cl中的基類a中的資料成員a
cl.a
::display();
//表示是派生類物件cl中的基類a中的成員函式display
//a,b同上
class c : public a, public b
};int main()
後果:
會產生同名覆蓋的問題,即最終訪問的就是派生類的成員(函式完全相同,否則為函式過載)
這裡函式屬於隱藏而不是覆蓋
這裡涉及到幾個概念:過載、覆蓋、隱藏2
輸出結果參考:
>cl x
.cpp
>x
.exe
c
#include
using
namespace
std;
class n
};class a: public n
;class b: public n
;class c: public a, public b
};int main()
繼承相當於對基類的拷貝,因此類a和類b中資料代表不同的儲存單元,因此都呼叫display時,還會導致:
>cl /ehsc x.cpp
用於 x86 的 microsoft (r) c/c++ 優化編譯器 18.00
.21005
x.cpp
x.cpp(30) : error c2385: 對「display」的訪問不明確
可能是「display」(位於基「n」中)
也可能是「display」(位於基「n」中)
x.cpp(30) : error c3861: 「display」: 找不到識別符號
摘取部落格:
↩詳見部落格
過載:相同的範圍(在同乙個類中)
覆蓋:派生類函式覆蓋基類虛函式 要求函式名字相同、引數相同
隱藏:(派生類的函式遮蔽了與其同名的基類函式)
如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無 virtual 關鍵字,基類的函式將被隱藏(注意別與過載混淆)
如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有 virtual關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆)
上面是部落格中的表達,感覺不準確,正確說法應該是:
當派生類中重寫了虛函式,那麼基類函式被覆蓋。
當派生類中寫了與基類同名的函式(引數相同或不同),那麼基類函式將被隱藏。
這裡的隱藏的概念是:根據指標型別,解析相應的函式
這部分內容在下一節有重疊的介紹 ↩
C 繼承 同名隱藏 覆蓋,虛函式
不同作用域宣告的識別符號的可見性原則 如果存在兩個或多個具有包含關係的作用域,外層宣告了乙個識別符號,而內層沒有再次宣告同名識別符號,那麼外層識別符號在內層依然可見,如果在內層宣告了同名識別符號,則外層識別符號在內層不可見,這時稱內層識別符號隱藏了外層同名識別符號,這種現象稱為隱藏規則。在類的派生層...
c 繼承 繼承 的二義性 虛函式
父類 plane 兩個類 乙個是標頭檔案 乙個是原始檔 pragma once include class plane 原始檔 include include include using namespace std plane plane name f 22 year 2010 plane plan...
類 虛函式分析
對於虛函式,雖然一直知道怎麼用,但是對其內部機制卻不清楚。今天寫了小段程式然後反彙編 class cbase void fun class ctest public cbase void fun void main 對以上反彙編後的關鍵 是 void main 結論 類的成員函式是所有類共享的,是存...