在程式設計中遇到乙個奇怪的問題, 在繼承類無法呼叫基類中定義的乙個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 ...