類的派生中 過載 重寫(覆蓋)隱藏 三種的區別
阿新 • • 發佈:2021-02-03
文章目錄
三者的定義
過載
是指同一可訪問區內被宣告的幾個具有不同引數列(引數的型別,個數,順序不同)的同名函式,根據引數列表確定呼叫哪個函式,過載不關心函式返回型別。
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); //錯誤,非過載。注意過載不關心函式返回型別。
};
重寫(覆蓋)
指派生類中存在重新定義的函式。其函式名,引數列表,返回值型別,所有都必須同基類中被重寫的函式一致。只有函式體不同(花括號內),派生類呼叫時會呼叫派生類的重寫函式,不會呼叫被重寫函式。重寫的基類中被重寫的函式必須有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;
}
隱藏
是指派生類的函式遮蔽了與其同名的基類函式,注意只要同名函式,不管引數列表是否相同,基類函式都會被隱藏。
#include "stdafx.h"
#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 個引數
Base *fd = &pd;
fd->fun(1.0,1);//Base::fun(double ,int);
fd->fun(1);//error
system("pause");
return 0;
}
兩兩之間的區別
隱藏和重寫的區別
靜態方法、成員變數不能重寫,只可以隱藏;例項方法可以重寫
重寫與隱藏的本質區別:
- 重寫是動態繫結,根據執行時引用所指向物件的實際型別來決定呼叫相關類的成員。
- 隱藏是靜態繫結的,根據編譯時引用的靜態型別來決定呼叫相關類的成員。
- 換句話,執行時候的區別在這裡
- 如果子類重寫了父類的方法,當父類的引用指向子類物件時,通過父類的引用呼叫的是子類的方法。
- 如果子類隱藏了父類的方法(成員變數),通過父類的引用呼叫的仍然是父類的方法(成員變數).
重寫和過載的區別
- 範圍區別:重寫和被重寫的函式在不同的類中,過載和被過載的函式在同一類中。
- 引數區別:重寫與被重寫的函式引數列表一定相同,過載和被過載的函式引數列表一定不同。
- virtual的區別:重寫的基類必須要有virtual修飾,過載函式和被過載函式可以被virtual修飾,也可以沒有
過載和隱藏的區別
- 範圍區別:過載是在同一個類中,隱藏是派生的類隱藏基類