很多人無法正確區分函式過載、函式隱藏與函式重寫這三個概念,下面將給這三個概念下個定義,並討論c++與c#中的異同。
過載函式(
overloaded function
):在相同的作用域中的函式名相同,而參數列不同,即通過函式的參數列而唯一標識並且來區分函式的一種特殊的函式。
在c++和c#中,都不能以返回值區分兩個函式。如果兩個函式是不同的函式,那麼這兩個函式的簽名不完全相同。函式簽名包括函式名、引數型別,引數個數和引數順序,不包括返回值。可以這麼理解:返回值為int和返回值為long 的函式都可以返回0,所以不能僅按返回值區分兩個函式。
在繼承與多型上,c++中,如果派生類中與基數存在同名函式(只要函式名相同),那麼基類中的所有同名函式都會被隱藏。如果要在派生類中呼叫基類的同名函式,可以採用類名
::函式名的方法。
在c#中,如果派生類中存在與基類函式簽名完全相同的函式,那麼基類中與之有完全相同的函式簽名的函式就會被隱藏,在派生類中應該在該函式前加上修飾符new來告訴編譯器我們是故意隱藏基類函式。在派生類中只會隱藏基類中有完全相同的函式簽名的函式,其他不同函式簽名的同名函式不會被隱藏,可以通過類似於過載函式的方法呼叫他們。這一點與c++是不同的,c++中,派生類中一旦出現同名函式,則基類中所有同名函式都被隱藏,必須使用類名
+::+
函式名來訪問基類的同名函式。
重寫用在多型性上,派生類對基數的虛函式的重定義稱為重寫(覆蓋)(override)。在c++與c#中,如果基類的函式用virtual修飾,那麼派生類中重寫該函式時,必須擁有完全相同的函式原型(包括返回值型別、函式名、引數型別、引數個數和引數順序)。
在c++中,如果基類中的函式有virtual修飾,那麼派生類中與之擁有相同函式簽名的函式就會被認為是在重寫基類的虛函式,而不會被認為是對基類函式的隱藏,這時,派生類中的該函式還要求必須與基類中的函式擁有相同的返回值。
而在c#中,若派生類中如果存在與基類函式簽名完全相同的函式,如果在派生類中使用override修飾,則被認為是在重寫基類的虛函式,這時又要求派生類中的該函式與基類中的函式要擁有相同的返回值;如果是用new修飾,則被認為是在隱藏基類的函式。只有被標記為virtual和abstract方法才能用override修飾並重寫。
在c++中,無論是在類中還是在類外,都可以用採類名
::函式名的形式訪問基類中的函式。而c#中只能在類中使用base.
函式名的形式訪問。下面的訪問是錯誤的:
derived d = newderived();
d.(base.fun());
C 函式的過載 重寫與隱藏
1 幾個概念與區別 1 函式重寫 也稱作覆蓋,是用於類的繼承中,函式名 引數個數 型別都相同,僅函式體不同。2 函式過載 是指同一作用域的不同函式使用相同的函式名,但是引數個數或型別不同。3 函式隱藏 既不是過載也不是重寫,例如 函式名及引數完全相同卻又不是虛函式,卻在子類中重新實現該函式,也就是所...
C 中過載與重寫與隱藏
include using namespace std class base void g float x virtual void h int x class derived public base void g int x void h float x 其中,class b void f dou...
C 函式的過載 重寫 隱藏
過載 1 在同一作用域中。2 函式名相同 引數個數或引數型別不同。3 過載又稱為靜態多型,靜態繫結,靜態決議等。因為要實現過載,所以c 和c的命名方式有所不同。過載主要是為了減輕程式設計師對函式名的記憶負擔,讓所有功能相似的函式使用同一名字。4 任何程式都僅有乙個 main 函式的例項。main 函...