天天看點

C++ 重載、重寫(覆寫)和隐藏的差別

重載(overload)

重載是指在同一範圍定義中的同名成員函數才存在重載關系。主要特點是函數名相同,參數類型和數目有所不同,不能出現參數個數和類型均相同,僅僅依靠傳回值不同來區分的函數。重載和函數成員是否是虛函數無關。舉個例子:

class A{
    ...
    virtual int fun();
    void fun(int);
    void fun(double, double);
    static int fun(char);
    ...
}
           

重寫(覆寫)(override)

重寫指的是在派生類中覆寫基類中的同名函數,重寫就是重寫函數體,要求基類函數必須是虛函數且:

  • 與基類的虛函數有相同的參數個數
  • 與基類的虛函數有相同的參數類型
  • 與基類的虛函數有相同的傳回值類型

舉個例子:

//父類
class A{
public:
    virtual int fun(int a){}
}
//子類
class B : public A{
public:
    //重寫,一般加override可以確定是重寫父類的函數
    virtual int fun(int a) override{}
}
           

重載與重寫的差別:

  • 重寫是父類和子類之間的垂直關系,重載是不同函數之間的水準關系
  • 重寫要求參數清單相同,重載則要求參數清單不同,傳回值不要求
  • 重寫關系中,調用方法根據對象類型決定,重載根據調用時實參表與形參表的對應關系來選擇函數體

隐藏(hide)

隐藏指的是某些情況下,派生類中的函數屏蔽了基類中的同名函數,包括以下情況:

兩個函數參數相同,但是基類函數不是虛函數。和重寫的差別在于基類函數是否是虛函數。舉個例子:

//父類
class A{
public:
    void fun(int a){
        cout << "A中的fun函數" << endl;
    }
};
//子類
class B : public A{
public:
    //隐藏父類的fun函數
    void fun(int a){
        cout << "B中的fun函數" << endl;
    }
};
int main(){
    B b;
    b.fun(2); //調用的是B中的fun函數
    b.A::fun(2); //調用A中fun函數
    return 0;
}
           

兩個函數參數不同,無論基類函數是不是虛函數,都會被隐藏。和重載的差別在于兩個函數不在同一個類中。舉個例子:

//父類
class A{
public:
    virtual void fun(int a){
        cout << "A中的fun函數" << endl;
    }
};
//子類
class B : public A{
public:
    //隐藏父類的fun函數
   virtual void fun(char* a){
       cout << "A中的fun函數" << endl;
   }
};
int main(){
    B b;
    b.fun(2); //報錯,調用的是B中的fun函數,參數類型不對
    b.A::fun(2); //調用A中fun函數
    return 0;
}
           

繼續閱讀