C 中的虛函式的隱藏規則

2021-06-01 04:41:19 字數 1839 閱讀 4744

在程式設計中遇到乙個奇怪的問題, 在繼承類無法呼叫基類中定義的乙個public函式, 編譯時總是說函式呼叫的參數列不正確, 很是鬱悶. 在網上搜尋之後, 發現原因是:

在基類中有定義有多個同名的函式(例如exec), 但參數列是不同的, 其中乙個是虛函式, 在繼承類中實現. 這樣的話, 在繼承類中就無法呼叫基類中定義的其他exec函式(只有繼承類中過載的exec函式才可呼叫), 這是由c++中的隱藏規則所決定的. 

現摘錄我所找到的資料以備查閱參考.

8.2.2 令人迷惑的隱藏規則

本來僅僅區別過載與覆蓋並不算困難,但是c++的隱藏規則使問題複雜性陡然增加。這裡「隱藏」是指派生類的函式遮蔽了與其同名的基類函式,規則如下:

(1)如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無virtual關鍵字,基類的函式將被隱藏(注意別與過載混淆)。

(2)如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有virtual關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆)。

示例程式8-2-2(a)中:

(1)函式derived::f(float)覆蓋了base::f(float)。

(2)函式derived::g(int)隱藏了base::g(float),而不是過載。

(3)函式derived::h(float)隱藏了base::h(float),而不是覆蓋。

示例8-2-2(a)成員函式的過載、覆蓋和隱藏

#include class base

void g(float x)

void h(float x)

};class derived : public base

void g(int x)

void h(float x)

};

據作者考察,很多c++程式設計師沒有意識到有「隱藏」這回事。由於認識不夠深刻,「隱藏」的發生可謂神出鬼沒,常常產生令人迷惑的結果。

示例8-2-2(b)中,bp和dp指向同一位址,按理說執行結果應該是相同的,可事實並非這樣。

示例8-2-2(b) 過載、覆蓋和隱藏的比較

void main(void)

8.2.3 擺脫隱藏

隱藏規則引起了不少麻煩。示例8-2-3程式中,語句pd->f(10)的本意是想呼叫函式base::f(int),但是base::f(int)不幸被derived::f(char*)隱藏了。由於數字10不能被隱式地轉化為字串,所以在編譯時出錯。

示例8-2-3 由於隱藏而導致錯誤

class base

;class derived : public base

;void test(void)

從示例8-2-3看來,隱藏規則似乎很愚蠢。但是隱藏規則至少有兩個存在的理由:

寫語句pd->f(10)的人可能真的想呼叫derived::f(char*)函式,只是他誤將引數寫錯了。有了隱藏規則,編譯器就可以明確指出錯誤,這未必不是好事。否則,編譯器會靜悄悄地將錯就錯,程式設計師將很難發現這個錯誤,流下禍根。

假如類derived有多個基類(多重繼承),有時搞不清楚哪些基類定義了函式f。如果沒有隱藏規則,那麼pd->f(10)可能會呼叫乙個出乎意料的基類函式f。儘管隱藏規則看起來不怎麼有道理,但它的確能消滅這些意外。

示例8-2-3中,如果語句pd->f(10)一定要呼叫函式base::f(int),那麼將類derived修改為如下即可。

class derived : public base

};

C 中的虛函式 純虛函式

c 最重要的特性就是多型,而多型,就主要通過虛函式實現的。具體的實現過程是 基類中的函式定義為虛函式,派生類發生覆蓋 即函式名稱 引數列表 返回值型別完全相同 的情況下,派生類中的函式也會自動變成虛函式,不論加不加virtual關鍵字。此時,基類與子類物件中都會存在一張虛函式表 因為含有虛函式 具體...

C 中的函式隱藏

只要基類在定義成員函式時已經宣告了virtual關鍵字,在派生類實現的時候覆蓋該函式時,virtual關鍵字可加可不加,不影響多型的實現。容易與隱藏混淆 隱藏是指派生類的函式遮蔽了與其同名的基類函式,規則如下 1 如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無virtual關鍵字,基...

C 中的虛函式

c 中的虛函式 virtual function 1.簡介 虛函式是c 中用於實現多型 polymorphism 的機制。核心理念就是通過基類訪問派生類定義的函式。假設我們有下面的類層次 class a class b public a 那麼,在使用的時候,我們可以 a a new b a foo ...