重寫 覆蓋 過載 隱藏 多型幾個概念的區別分析

2021-06-05 14:59:11 字數 2532 閱讀 1537

override->重寫(=覆蓋)、overload->過載、polymorphism -> 多型

override是重寫(覆蓋)了乙個方法,以實現不同的功能。一般是用於子類在繼承父類時,重寫(重新實現)父類中的方法。

成員函式的過載(overload)、覆蓋(override)與隱藏很容易混淆,c++程式設計師必須要搞清楚概念,否則錯誤將防不勝防。

1   過載與覆蓋

成員函式被過載的特徵:

(1)相同的範圍(在同乙個類中)   ;

(2)函式名字相同;

(3)引數不同;

(4)virtual   關鍵字可有可無。

覆蓋是指派生類函式覆蓋基類函式,特徵是:

(1)不同的範圍(分別位於派生類與基類)   ;

(2)函式名字相同;

(3)引數相同;

(4)基類函式必須有   virtual   關鍵字。

示   例   1   中   ,   函   數   base::f(int)   與   base::f(float)   相互過載,   而   base::g(void)   被   derived::g(void)覆蓋。

#include  

class   base

...void   f(float   x)...

virtual   void   g(void)...

}; class   derived   :   public   base

...};

void   main(void)

...

示例   1   成員函式的過載和覆蓋

2   令人迷惑的隱藏規則

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

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

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

示例程式   2(a)中:

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

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

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

#include  

class   base

...void   g(float   x)...

void   h(float   x)...

}; class   derived   :   public   base

...void   g(int   x)...

void   h(float   x)...

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

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

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

void   main(void)

...

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

3   擺脫隱藏

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

class   base

...;

class   derived   :   public   base

...;

void   test(void)

...

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

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

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

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

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

class   derived   :   public   base

...

};  

重寫 覆蓋 過載 隱藏 多型幾個概念的區別分析

override 重寫 覆蓋 overload 過載 polymorphism 多型 override是重寫 覆蓋 了乙個方法,以實現不同的功能。一般是用於子類在繼承父類時,重寫 重新實現 父類中的方法。成員函式的過載 overload 覆蓋 override 與隱藏很容易混淆,c 程式設計師必須要...

重寫 覆蓋 過載 隱藏 多型幾個概念的區別分析

override 重寫 覆蓋 overload 過載 polymorphism 多型 override是重寫 覆蓋 了乙個方法,以實現不同的功能。一般是用於子類在繼承父類時,重寫 重新實現 父類中的方法。成員函式的過載 overload 覆蓋 override 與隱藏很容易混淆,c 程式設計師必須要...

重寫 覆蓋 過載 多型幾個概念的區別

override 重寫 覆蓋 overload 過載 polymorphism 多型 override 是重寫了乙個方法,已實現不同的功能。一般是子類繼承父類時,重寫 重新實現 父類的方法。重寫 覆蓋 的規則 1 重寫的方法引數列表必須完全與被重寫的方法相同,否則不能稱其重寫而是過載。2 重寫的方法...