成員函數的重載,覆蓋與隱藏

成員函數的重載,覆蓋和隱藏是三個很容易混淆的概念,下面我們來區分一下這三者

一 重載的特點
1 兩個函數處於同一作用域中(即同一個類中)
2 函數名要相同
3 參數不相同(參數的個數,參數的類型,參數的順序)
4 返回值可同可不同
5 virtual關鍵字可有可無

二 覆蓋(重寫)的特點
1 兩個在不同作用域中(基類與派生類)
2 函數名相同
3 參數相同
4 基類必須要有virtual關鍵字
5返回值類型相同(除了協變)
此時基類的該函數被派生類的同名函數覆蓋
三 隱藏的特點
1 兩個函數處於不同的作用域中(基類與派生類)
2 函數名相同但是參數不同,無論有無virtual,基類的函數被派生類的同名函數隱藏
3 函數名相同,參數相同,基類中該函數沒有virtual關鍵字,基類的函數被派生類的同名函數隱藏

下面看個例子體會下隱藏和覆蓋的區別:


class Base
{
public:
    Base(int x)
    {
        a = x;
    }
    virtual void f1()
    {
        cout <<a<<" "<< "Base::f1 ()" << endl;
    }
    int f2()
    {
        cout << a << " " << "Base::f2() " << endl;
        return 0;
    }
    void f3()
    {
        cout << a << " " << "Base::f3() " << endl;
    }
    virtual Base*f4() //協變,還可爲 virtual Base&f4()
    {
        cout << a << " " << "Base::f4()" << endl;
        return this;
    }
private:
    int a;
};
class Derived :public Base
{
public:
    Derived(int x, int y) :Base(x), b(y){}
    virtual void f1()
    {
        cout << b << " " << "Derived::f1 () " << endl;
    }
    void f2()
    {
        cout << b << " " << "Derived::f2() " << endl;
    }
    void f3(int)
    {
        cout << b << " " << "Derived::f3()" << endl;
    }
    virtual Derived*f4()  //協變還可爲virtual Derived&f4()
    {
        cout << b << " " << "Derived::f4()" << endl;
        return this;
    }
private:
    int b;
};

int main()
{
    Base b(1);
    Derived d(2, 3);
    Base*pb = &b;
    pb->f1();// 1  Base :: f1()
    pb->f2();// 1  Base :: f2()
    pb->f3();// 1  Base :: f3()
    pb->f4();// 1  Base :: f4()

    pb = &d;
    pb->f1();//3   Derived :: f1()
    pb->f2();//2   Base  :: f2()
    pb->f3();//2   Base  :: f3()
    pb->f4();//3   Derived  :: f4()
    return 0;
}

Derived 中f1,f4函數重寫了Base中f1,f4
f2,f3隱藏了Base中f2,f3

發佈了49 篇原創文章 · 獲贊 11 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章