1. 程式人生 > >C++函式的過載、重寫與隱藏

C++函式的過載、重寫與隱藏

1、幾個概念與區別
(1)函式重寫:也稱作覆蓋,是用於類的繼承中,函式名、引數個數、型別都相同,僅函式體不同。
(2)函式過載:是指同一作用域的不同函式使用相同的函式名,但是引數個數或型別不同。
(3)函式隱藏:既不是過載也不是重寫,例如:函式名及引數完全相同卻又不是虛擬函式,卻在子類中重新實現該函式,也就是所謂的隱藏。

2、重寫/覆蓋
(1)重寫是指派生類函式覆蓋基類函式。
(2)重寫的特徵:
①不同的作用域(分別位於派生類與基類);
②函式名字相同;
③引數相同;
④基類函式必須是虛擬函式;
⑤重寫函式必須和原函式具有相同的返回型別;
⑥const可能會使虛成員函式的重寫失效。
(3)函式重寫例子

#include <iostream>
using namespace std;

class A
{
protected:
    int k;
public:
    A(){ k = 3;}
    virtual int  getValue(){return k;}
};

class B:public A
{
public:
    virtual int getValue(){return k*2;}
};

void F(A *p)
{
    cout << p->getValue() << endl;
}

int main()
{
    A *ba = new
A; B *bp = new B; cout << sizeof(ba) << endl; cout << sizeof(*ba) << endl; F(bp); return 0; }

執行結果:這裡寫圖片描述

3、函式隱藏
(1)隱藏,是指派生類的函式遮蔽遮蔽了與其同名的基類函式。
(2)特徵:
①如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無virtual關鍵字,基類的函式都將被隱藏。(注意與過載區分)
②如果派生類的函式與基類的函式同名,且引數也相同,但是基類函式沒有virtual關鍵字。此時,基類的函式被隱藏。(注意與覆蓋區分)
(3)函式隱藏例子:

//派生類將隱藏基類的方法

#include <iostream>
using namespace std;

class Base
{
public:
       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:
       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;

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

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

執行結果:這裡寫圖片描述

4、成員函式被過載的特徵
(1)相同的作用域(同一個類中);
(2)函式名字相同;
(3)引數不同;
(4)virtual關鍵字可有可無。

#include <iostream>
using namespace std;

int add(int,int);
double add(double,double);

int add(int x, int y)
{
    cout << "int" <<endl;
    return x+y;
}

double add(double x, double y)
{
    cout << "double " <<endl;
    return x+y;
}

int main(void)
{
    cout << add(5,10) <<endl;
    cout << add(5.2,10.3) << endl;

    return 0;
}

執行結果:這裡寫圖片描述