1. 程式人生 > >C++ overload、override、overwrite

C++ overload、override、overwrite

對於函式的過載(overload)、覆蓋(override)、重寫(overwrite)三者的理解,通過程式碼來分析。

過載:是指同一可訪問區內被宣告的幾個具有不同引數列(引數的型別,個數,順序不同)的同名函式,根據引數列表確定呼叫哪個函式,過載解析中不考慮返回型別,而且在不同的作用域裡宣告的函式也不算是過載。

class A{
public:
  void func(int i);
  void func(double i);//overload
  void func(int i, double j);//overload
  void func(double i, int j);//overload
int func(int i); //非過載。注意過載考慮函式返回型別。 };

覆蓋:是指派生類中存在重新定義的函式。其函式名,引數列表,返回值型別,所有都必須同基類中被重寫的函式一致。只有函式體不同(花括號內),派生類呼叫時會呼叫派生類的重寫函式,不會呼叫被重寫函式。重寫的基類中被重寫的函式必須有virtual修飾。

#include<iostream>
using namespace std;

class Base
{
public:
    virtual void fun(int i){ cout << "Base::fun(int) : "
<< i << endl;} }; class Derived : public Base { public: virtual void fun(int i){ cout << "Derived::fun(int) : " << i << endl;} }; int main() { Base b; Base * pb = new Derived(); //向上造型 pb->fun(3); //Derived::fun(int) delete pb; system("pause"
); return 0; }

重寫
是指派生類的函式遮蔽了與其同名的基類函式,規則如下:
(1)如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無virtual關鍵字,基類的函式將被隱藏。
(2)如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有virtual關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆)。

class Base{
public:
    virtual int fcn();
};
class D1:public Base{
public:
    //隱藏基類的fcn,這個fcn不是虛擬函式
    //D1繼承了Base::fcn()的定義
    int fcn(int);         //形參類別與Base中的fcn不一樣
    virtual void f2();    //是一個新的虛擬函式,在Base中不存在
};
class D2:public D1{
publicint fcn(int);        //是一個非虛擬函式,隱藏了D1::fcn(int)
    int fcn();           //覆蓋了Base的虛擬函式fcn
    void f2();           //覆蓋了D1的虛擬函式f2

D1的fcn函式並沒有覆蓋Base的虛擬函式fcn,原因是他們的形參列表不同。實際上,D1的fcn將隱藏Base的fcn。此時擁有了兩個名為fcn的函式,一個D1從Base繼承而來的虛擬函式fcn,另一個是D1自己定義的接收一個int引數的非虛擬函式fcn。

下面寫一個例子,可以通過定義基類是否有virtual關鍵字來幫助判斷。

// test.cpp : 定義控制檯應用程式的入口點。

#include "stdafx.h"
#include <iostream>
using namespace std;

class A {
public:
    A() {}
    void print(int x);    //定義函式
    void print(int x, int y);
    void print();
    ~A() {}
};
void A::print(int x)
{
    cout << "A::print(int x)" << endl;
}
void A::print(int x, int y)
{
    cout << "A::print(int x,int y)" << endl;
}
void A::print()
{
    cout << "A::print()" << endl;
}
class B :public A {
public:
    B() {}
    void print(int x);
    ~B() {}
};

int main()
{
    A a;
    B b;
    a.print(1);
    a.print(1,2);
    b.print(1);
    b.print(1,2);     //錯誤,函式不接受2個引數
    return 0;
}

在上面的b.print(1,2) 中提示錯誤,其實是如果基類定義了overloaded(過載)函式,那麼在子類必須override(覆蓋)所有你所定義的overloaded(過載)函式,不能只override一個,如果沒有override所有過載函式,那麼沒有被override的將會被隱藏,只能父類呼叫,不能子類呼叫。