函數重載(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();
- }
本文轉自:http://blog.csdn.net/xiejingfa/article/details/48496593