C 虛函式分析 1 同名函式繼承二義性問題

2021-07-10 20:01:44 字數 2015 閱讀 6830

在討論虛函式之前,首先看一下類中同名函式的問題

多重繼承,最常見的問題就是繼承的成員同名而產生的二義性(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 結論 類的成員函式是所有類共享的,是存...