【C++拾遺】 C++函式過載、重寫、重定義的區別
阿新 • • 發佈:2019-02-16
原創作品,轉載請標明:http://blog.csdn.net/xiejingfa/article/details/48496593
函式過載(overload)
函式過載是指在一個類中宣告多個名稱相同但引數列表不同的函式,這些的引數可能個數或順序,型別不同,但是不能靠返回型別來判斷。特徵是:
(1)相同的範圍(在同一個作用域中);
(2)函式名字相同;
(3)引數不同;
(4)virtual 關鍵字可有可無(注:函式過載與有無virtual修飾無關);
(5)返回值可以不同;
函式重寫(也稱為覆蓋 override)
函式重寫是指子類重新定義基類的虛擬函式。特徵是:
(1)不在同一個作用域(分別位於派生類與基類);
(2)函式名字相同;
(3)引數相同;
(4)基類函式必須有 virtual 關鍵字,不能有 static 。
(5)返回值相同,否則報錯;
(6)重寫函式的訪問修飾符可以不同;
重定義(也稱隱藏)
(1)不在同一個作用域(分別位於派生類與基類) ;
(2)函式名字相同;
(3)返回值可以不同;
(4)引數不同。此時,不論有無 virtual 關鍵字,基類的函式將被隱藏(注意別與過載以及覆蓋混淆);
(5)引數相同,但是基類函式沒有 virtual關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆);
例子
輸出:#include <iostream> using namespace std; class Base { public: // ========================================================================= // 子類和父類返回值引數相同,函式名相同,有/無virtual關鍵字 // ========================================================================= // 若無virtual關鍵字,則在子類中宣告與父類同名的方法,從而覆蓋了父類的方法(函式重定義) void a() { cout << "Base::a()" << endl; }; // 若有virtual關鍵字,即為虛擬函式。由物件的型別決定呼叫哪個函式(多型,函式重寫override)。 virtual void b() { cout << "Base::b()" << endl; } // ========================================================================= // 子類和父類返回值引數不同,函式名相同,有/無virtual關鍵字 // ========================================================================= // 若無virtual關鍵字,父類的同名成員被隱藏。 void d(int x) { cout << "Base::d() x = " << x << endl; } // 若有virtual關鍵字,父類的同名成員同樣被隱藏。 virtual void e(int x) { cout << "Base::e() x = " << x << endl; } // ========================================================================= // 子類和父類返回值引數相同,函式名相同,函式返回值不同,有/無virtual關鍵字 // ========================================================================= // 若無virtual關鍵字(函式重寫,這種情況不屬於“函式過載”範疇) void f() { cout << "void Base::f()" << endl; } // 若有virtual關鍵字 (報錯) virtual void g() { cout << "virtual void Base::g()" << endl; } }; class Derived : public Base { public: // ========================================================================= // 子類和父類返回值引數相同,函式名相同,有/無virtual關鍵字 // ========================================================================= // 覆蓋了父類同名方法(函式重寫) void a() { cout << "Derived::a()" << endl; } // 多型 virtual void b() { cout << "Derived::b()" << endl; } // ========================================================================= // 子類和父類返回值引數不同,函式名相同,有/無virtual關鍵字 // (注:函式過載與virtual關鍵字有無沒有關係) // ========================================================================= // 父類同名成員被隱藏 void d(int x, int y) { cout << "Derived::d() x = " << x << " y = " << y<< endl; } // 父類同名成員被隱藏 virtual void e(int x, int y) { cout << "Derived::e() x = " << x << " y = " << y << endl; } // ========================================================================= // 子類和父類返回值引數相同,函式名相同,函式返回值不同,有/無virtual關鍵字 // ========================================================================= // 返回值與基類不同 int f() { cout << "int Derived::f()" << endl; return 1; } //// 錯誤 //virtual int g() //{ // cout << "virtual int Base::g()" << endl; // return 1; //} }; int main() { // 用作引數 int xx = 100; cout << "子類和父類返回值引數相同,函式名相同,無virtual關鍵字" << endl; Derived d; d.a(); d.Base::a(); // 顯示呼叫基類方法 cout << "子類和父類返回值引數相同,函式名相同,有virtual關鍵字" << endl; Base* b = new Derived; b->b(); cout << "子類和父類返回值引數不同,函式名相同,無virtual關鍵字" << endl; d.d(xx, xx); // d.d(xx); // 報錯 d.Base::d(xx); // 顯示呼叫 cout << "子類和父類返回值引數不同,函式名相同,有virtual關鍵字" << endl; d.e(xx, xx); //d.e(xx); // 報錯 d.Base::e(xx); cout << "子類和父類返回值引數相同,函式名相同,函式返回值不同, 無virtual關鍵字" << endl; d.f(); d.Base::f(); }