標籤:編譯 virtual 分享 include 失敗 函數 需要 height virt
C++ 代碼:
#include <iostream>#include <string>using namespace std;class Parent{public: void fun() {cout<<"Parent fun"<<endl;} void fun(int a) {cout<<"Parent fun int a"<<endl;} void fun(int a, int b) {cout<<"Parent fun int a int b"<<endl;}};class Child:public Parent{public: void fun() {cout<<"Child fun"<<endl;} //void fun(int a) //{cout<<"Child fun int a"<<endl;} //void fun(int a, int b) //{cout<<"Child fun int a int b"<<endl;}};int main(){ Child x; x.fun(); //x.fun(0); return 0;}
運行結果:
若是將主函數修改為:
int main(){ Child x; x.fun(); x.fun(0); return 0;}
運行結果:
分析,說明:
在c++中,重載不會發生在基類與衍生類別之間,重載 制發生在同一類中!當基類和衍生類別中存在同名函數時,無論同名函數的形參個數或者類型是否相同,衍生類別中的同名函數都會將基類中的同名函數隱藏(將在下邊說明隱藏)掉,而不會是重載關係。這時,當你通過衍生類別對象調用該同名函數時,只能訪問衍生類別的該函數,如果硬要訪問基類的該函數,則需要在函數名前加上類範圍!
如果將衍生類別中的同名函數 設為 static 靜態, 運行效果如上不變。
class Child:public Parent{public: static void fun() {cout<<"Child fun"<<endl;} //void fun(int a) //{cout<<"Child fun int a"<<endl;} //void fun(int a, int b) //{cout<<"Child fun int a int b"<<endl;}};
如果將父類中的同名函數 設為 static 靜態, 運行效果如上仍不變。
class Parent{public: static void fun() {cout<<"Parent fun"<<endl;} static void fun(int a) {cout<<"Parent fun int a"<<endl;} static void fun(int a, int b) {cout<<"Parent fun int a int b"<<endl;}};
C++ 中 同名函數是否為 靜態 static , 不影響 繼承中的覆蓋 關係。總之, c++中的 重載 只發生在同一類中, 也就是說 C++的繼承存在隱藏。
在c++中隱藏只能出現在基類和衍生類別之間,而不能發生在同一個類內(否則會引起編譯器出現二義性)。當基類和衍生類別中存在同名函數時,無論同名函數的形參個數或者類型是否相同,衍生類別中的同名函數都會將基類中的同名函數(這個函數不論是靜態或者是非靜態都可以,如上述例子)隱藏掉,而不會是重載關係。這時,當你通過衍生類別對象調用該同名函數時,只能訪問衍生類別的該函數,如果硬要訪問基類的該函數,則需要在函數名前加上類範圍!
若是 子類中的同名函數 傳回值不同,如下,仍然會覆蓋父類同名函數,即c++繼承中的 覆蓋及其隱藏 只和 函數名 相同與否 有關。
當是虛函數的情況:
#include <iostream>#include <string>using namespace std;class Parent{public: virtual void fun() {cout<<"Parent fun"<<endl;} void fun(int a) {cout<<"Parent fun int a"<<endl;} void fun(int a, int b) {cout<<"Parent fun int a int b"<<endl;}};class Child:public Parent{public: int fun() {cout<<"Child fun"<<endl;return 0;}};int main(){ Child x; x.fun(); return 0;}
運行結果:
對於虛函數(用virtual修飾的),如果基類中有一個虛函數,衍生類別中同樣有一個同名同參的函數(那麼該函數將自動虛化), 那麼其傳回值一定要和基類的虛函數的傳回值相同!否則 覆蓋失敗,編譯不通過,隱藏失敗!
java 部分:
如上述代碼所示。而在java中子類會將父類中的方法繼承過來,子類中同名方法會和父類中的同名方法要麼是重載關係,要麼是覆蓋關係,要麼就錯誤(比如同名同參卻是不同的傳回型別!)
class Parent{public static void fun() {System.out.println("Parent fun");}public static void fun(int a) {System.out.println("Parent fun int a");}public static void fun(int a, int b) {System.out.println("Parent fun int a int b");}};class Child extends Parent {public static void fun() {System.out.println("Child fun");}//public void fun(int a)// {System.out.println("Child fun int a");}//public void fun(int a, int b)// {System.out.println("Child fun int a int b");}};public class dev{ public static void main(String []args) { Child x=new Child(); x.fun(); x.fun(0); }}
若是,去掉 子類中 的 static , 無法編譯, 即 java 繼承中的覆蓋 要求 區分 static, 即static 同名函數 覆蓋父類的static 同名函數。
如果父類 同名函數 無static , 子類同名函數有 static, 即
在java中, 非靜態方法只能由(或被)非靜態方法 覆蓋! 靜態方法只能由(或被)靜態方法 覆蓋!
即,static 對應相同。
c++ 與 java 中的 繼承