函式的過載、重寫、重定義
阿新 • • 發佈:2019-01-06
函式過載(overload)
函式過載是指在一個類中宣告多個名稱相同但引數列表不同的函式,這些的引數可能個數或順序,型別不同,但是不能靠返回型別來判斷。特徵是:
(1)相同的範圍(在同一個作用域中);
(2)函式名字相同;
(3)引數不同;
(4)virtual 關鍵字可有可無(注:函式過載與有無virtual修飾無關);
(5)返回值可以不同;
函式重寫(也稱為覆蓋 override)
函式重寫是指子類重新定義基類的虛擬函式。特徵是:
(1)不在同一個作用域(分別位於派生類與基類);
(2)函式名字相同;
(3)引數相同;
(4)基類函式必須有 virtual 關鍵字,不能有 static 。
(5)返回值相同,否則報錯;
(6)重寫函式的訪問修飾符可以不同;
過載與覆蓋的區別:
(1)覆蓋是子類和父類之間的關係,是垂直關係;過載是同一個類中不同方法之間的關係,是水平關係;
(2)覆蓋要求引數列表相同,過載要求引數列表不同;覆蓋要求返回型別相同,過載則不要求;
(3)覆蓋關係中,呼叫方法體是根據物件的型別(基類型別還是派生類型別)來決定的,過載關係是根據呼叫時的實參表與形參表來選擇方法體的。
重定義(也稱隱藏)
(1)不在同一個作用域(分別位於派生類與基類) ;
(2)函式名字相同;
(3)返回值可以不同;
(4)引數不同。此時,不論有無 virtual 關鍵字,基類的函式將被隱藏(注意別與過載以及覆蓋混淆);
(5)引數相同,但是基類函式沒有 virtual關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆);
程式碼舉例
#include <iostream> using namespace std; class Base { public: void a() { cout << "void Base::a()" << endl; } //過載了上面的void a()函式,發生在同一個類中 void a(int i) { cout << "void Base::a(int i)" << endl; } virtual void b() { cout << "virtual void Base::b()" << endl; } virtual void c() { cout << "virtual void Base::c()" << endl; } virtual void d() { cout << "virtual void Base::d()" << endl; } private: int x; }; class Derived :public Base { public: //在基類Base中,函式a不是虛擬函式,所以這裡是重定義 void a() { cout << "void Derived::a()" << endl; } //引數不同。此時,不論無論有無virtual 關鍵字,基類的函式將被隱藏,屬於重定義 void b(float f) { cout << "virtual void Derived::b(float f)" << endl; } /* //編譯器報錯,也就是說編譯器認為函式名和引數都與基類的虛擬函式c相同,那麼返回值也必須相同 //要麼,你就別讓編譯期認為這是多型,也就是別和基類設定一樣的函式名或引數,改變其一即可 float c() { cout << "virtual float Derived::c()" << endl; return 1.1; } */ //父類中定義了虛擬函式,子類與父類函式名字相同,引數相同,返回值相同,屬於函式重寫 void d() { cout << "virtual void Derived::d()" << endl; } }; int main() { int i = 6; float f = 'a'; Base base; base.a(); base.a(i); base.b(); base.c(); base.d(); Derived derived; derived.a(); derived.b(f); derived.d(); system("pause"); return 0; }