我們在學習c++中總會有很多概念容易搞混,其中成員函式的過載、覆蓋和隱藏這三個概念就經常讓很多人頭大。
下面我們就來介紹一下這三個的區別:
成員函式被過載的條件是:
(1)相同的範圍也就是要在同乙個類中
(2)函式名字相同
(3)引數不同(這裡包括引數型別,引數的順序,引數的個數)
(4)virtual關鍵字可有可無
覆蓋是指派生類函式覆蓋基類函式,特徵是:
(1)不同的範圍也就是必須乙個位於基類乙個位於派生類
(2)函式名字相同
(3)引數要相同
(4)基類函式必須有virtual關鍵字
舉個例子:
#includeusing namespace std;
class base
void f(float x)
virtual void g(void)
};class derived :public base
};void main()
執行結果:
在上面程式中:
base::f(int)與base:f(float)構成過載
base::g(void)和base::g(void)構成覆蓋,派生類的g函式覆蓋基類的g函式
從上面看過載和覆蓋區分起來並不那麼困難,但是c++還存在隱藏規則問題使問題的複雜性就提高了
隱藏是指派生類的函式遮蔽了與其同名的基類函式,隱藏規則如下:
(1)如果派生類的函式名和基類的函式名相同但是引數不同,此時不論有沒有virtual關鍵字,基類的函式將被隱藏(這裡容易和過載混淆)
(2)如果派生類的函式和基類的函式函式名相同,引數也相同,但是基類函式沒有virtual關鍵字,此時基類的函式被隱藏(這裡容易和覆蓋混淆)
下面再看乙個例子:
#includeusing namespace std;
class base
void g(float x)
void h(float x)
};class derived :public base
void g(int x)
void h(float x)
};
(1)函式derived::f(float x)覆蓋了base::f(float)
(2)函式derived::g(int)隱藏了base::g(float);
(3)函式derived::h(float)隱藏了base::h(float);
還是有很多人注意不到隱藏這回事,由於沒有認識到「隱藏」,隱藏的發生可以被稱為神出鬼沒,常常產生令人疑惑的結果
比如下面這個例子:
void main(void)
執行結果如下:
上面的**我們看到pd和pb指向同乙個位址按道理說結果應該一樣,可是結果卻不像我們想象的那樣。
擺脫隱藏:
我們知道隱藏引起了很多麻煩,例如下面這個例子:
class base
;class derived:public base
;void test()
語句pd->f(10);本意是想呼叫函式base::f(int),但是不幸的是base::f(int)被derived::f(char*)隱藏了,因為int不能隱式轉化為字串,所以編譯時出錯。
既然隱藏帶來這麼多問題,為什麼還要存在呢,不是自找麻煩嗎?
實際上隱藏還是有它的用處的,至少它有兩個存在的理由:
(1)寫語句pd->f(10)的人可能真的想呼叫derived::f(char*)函式,只是他將引數寫錯了,這時候他就可以根據編譯報錯改正然後得出正常結果了。有了隱藏規則編譯器就可以明確指出錯誤了,這未必不是好事,否則編譯器只會將錯就錯,程式設計師將很難發現這個錯誤,留下禍根。
(2)假如類derived有多個基類(多重繼承),有時搞不清楚是那個基類定義了函式f。如果沒有隱藏規則,那麼pd->f(10)可能會呼叫乙個出乎意料的基類函式f。儘管隱藏規則看起來不那麼有道理,但它的確能消滅這些意外。
如果語句pd->f(10)一定要呼叫函式base::f(int),那麼將類derived改為:
C 成員函式的過載,覆蓋,隱藏
對於物件導向程式設計的三個特性 封裝,繼承,多型。封裝 封裝的目的主要是為了實現源 的安全性。所以我們對其有訪問控制。c 語言使用了三個明確的關鍵字來設定類中的邊界 public,private,protected。繼承的類可以訪問protected成員,但是不能訪問私有成員。繼承 重用介面,如果乙...
成員函式的過載,覆蓋和隱藏
什麼是函式過載 在c 程式中,可以將語義,功能相似的函式用同乙個名字表示,即就是函式過載。函式過載的原因 1 便於記憶,提高函式的易用性 2 類的建構函式需要過載機制 因為c 規定建構函式與類同名,建構函式只能有乙個名字,若要有不同的方法建立物件,只能依靠過載 成員函式被過載的特徵 1 在同乙個類範...
C 成員函式過載 覆蓋 重寫 和隱藏
區分成員函式過載 覆蓋 重寫 和隱藏的不同含義,禁止用隱藏方式定義非virtual成員函式 成員函式被過載的特徵 1 相同的範圍 在同乙個類中 2 函式名字相同 3 引數不同 覆蓋是指派生類函式覆蓋基類函式,特徵是 1 不同的範圍 分別位於派生類與基類 2 函式名字相同 3 引數相同 4 基類函式必...