1. 程式人生 > >C++中過載、重寫(覆蓋)和隱藏的區別

C++中過載、重寫(覆蓋)和隱藏的區別

基本概念:
過載:是指同一可訪問區內被宣告的幾個具有不同引數列(引數的型別,個數,順序不同)的同名函式,根據引數列表確定呼叫哪個函式,過載不關心函式返回型別。

示例:

class A{
public:
  void test(int i);
  void test(double i);//overload
  void test(int i, double j);//overload
  void test(double i, int j);//overload
  int test(int i);         //錯誤,非過載。注意過載不關心函式返回型別。
};

隱藏:是指派生類的函式遮蔽了與其同名的基類函式,注意只要同名函式,不管引數列表是否相同,基類函式都會被隱藏。

示例:

#include <iostream>
using namespace std;

class Base
{
public:
    void fun(double ,int ){ cout << "Base::fun(double ,int )" << endl; }
};

class Derive : public Base
{
public:
    void fun(int ){ cout << "Derive::fun(int )" << endl; }
};

int main()
{
    Derive pd;
    pd.fun(1
);//Derive::fun(int ) pb.fun(0.01, 1);//error C2660: “Derive::fun”: 函式不接受 2 個引數 system("pause"); return 0; }

重寫(覆蓋):是指派生類中存在重新定義的函式。其函式名,引數列表,返回值型別,所有都必須同基類中被重寫的函式一致。只有函式體不同(花括號內),派生類呼叫時會呼叫派生類的重寫函式,不會呼叫被重寫函式。重寫的基類中被重寫的函式必須有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) system("pause"); return 0; }

過載和重寫的區別

(1)範圍區別:重寫和被重寫的函式在不同的類中,過載和被過載的函式在同一類中。

(2)引數區別:重寫與被重寫的函式引數列表一定相同,過載和被過載的函式引數列表一定不同。

(3)virtual的區別:重寫的基類必須要有virtual修飾,過載函式和被過載函式可以被virtual修飾,也可以沒有。

隱藏和重寫,過載的區別

(1)與過載範圍不同:隱藏函式和被隱藏函式在不同類中。

(2)引數的區別:隱藏函式和被隱藏函式引數列表可以相同,也可以不同,但函式名一定同;當引數不同時,無論基類中的函式是否被virtual修飾,基類函式都是被隱藏,而不是被重寫。
示例

#include <iostream>

using namespace std;

class Base
{
public:
    virtual void f(float x){ cout << "Base::f(float) " << x << endl; }
    void g(float x){ cout << "Base::g(float) " << x << endl; }
    void h(float x){ cout << "Base::h(float) " << x << endl; }
};

class Derived : public Base
{
public:
    virtual void f(float x){ cout << "Derived::f(float) " << x << endl; }
    void g(int x){ cout << "Derived::g(int) " << x << endl; }
    void h(float x){ cout << "Derived::h(float) " << x << endl; }
};

int main(void)
{
    Derived d;
    Base *pb = &d;
    Derived *pd = &d;
    // Good : behavior depends solely on type of the object
    pb->f(3.14f); //Derived::f(float) 3.14
    pd->f(3.14f); //Derived::f(float) 3.14

    // Bad : behavior depends on type of the pointer
    pb->g(3.14f); //Base::g(float) 3.14
    pd->g(3.14f); //Derived::g(int) 3

    // Bad : behavior depends on type of the pointer
    pb->h(3.14f); //Base::h(float) 3.14
    pd->h(3.14f); //Derived::h(float) 3.14

    system("pause");
    return 0;
}

(1)函式Derived::f(float)覆蓋了Base::f(float)。

(2)函式Derived::g(int)隱藏了Base::g(float),而不是過載。

(3)函式Derived::h(float)隱藏了Base::h(float),而不是覆蓋。