C/C++—— C++中函式重寫和函式過載

readyao發表於2016-04-04

函式過載

1.必須在同一個類中進行。
2.子類無法過載父類的函式,父類同名函式將被名稱覆蓋。
3.過載是在編譯期間根據引數型別和個數決定函式呼叫。

如果父類中有函式:

void func()
{
     cout<<"Parent01:void func()"<<endl;
}

virtual void func(int i)
{
     cout<<"Parent:void func(int i)"<<endl;
}

virtual void func(int i, int j)
{
     cout<<"Parent:void func(int i, int j)"<<endl;
}

子類中有函式:

void func(int i, int j)
{
     cout<<"Child:void func(int i, int j)"<<" "<<i + j<<endl;
}

void func(int i, int j, int k)
{
     cout<<"Child:void func(int i, int j, int k)"<<" "<<i + j + k<<endl;
}

定義子類Child c;
問題1:c.func();可以執行嗎??
答案是不能:因為子類無法過載父類的函式,父類同名函式將被名稱覆蓋。子類中的func(int, int j);和func(int i, int j, int k);將父類中的func()函式覆蓋了。
如果想呼叫父類的func()函式,需要執行c.Parent01::func();加上函式的類限定符.

函式重寫

1.必須發生於父類與子類之間。
2.並且父類與子類中的函式必須有完全相同的原型。
3.使用virtual宣告之後能夠產生多型(如果不使用virtual,那叫重定義)。
4.多型是在執行期間根據具體物件的型別決定函式呼叫。

在上面例子中:子類中的func(int, int j);和func(int i, int j, int k);重寫了父類中的這兩個函式(因為這兩個函式是虛擬函式)。

測試案例:

#include <cstdlib>
#include <iostream>
using namespace std;

class Parent01
{
public:
    Parent01()
    {
        cout<<"Parent01:printf()..do"<<endl;
    }
public:
    void func()
    {
        cout<<"Parent01:void func()"<<endl;
    }

    void abcd()
    {
        cout<<"Parent01:void func()"<<endl;
    }

    virtual void func(int i)
    {
        cout<<"Parent:void func(int i)"<<endl;
    }

    virtual void func(int i, int j)
    {
        cout<<"Parent:void func(int i, int j)"<<endl;
    }
};

//重寫的兩種情況
//如果函式重寫,在父類中增加了virtual關鍵字, 將能產生多型。。。。
//如果函式重寫,沒有加virtual關鍵字,,相當於在子類中重定義。。。。。,不會發生多型。。。
class Child01 : public Parent01
{

public:

    //原因是發生了 名稱覆蓋,把子類中的沒有函式引數的,這個函式abcd名稱覆蓋了。。。
    //在子類中,是不能過載父類的函式的。編譯器就是這麼做的,順從。。。。
    void abcd(int a, int b)
    {
        cout<<"Parent01:void func()"<<endl;
    }

    //此處2個引數,和子類func函式是什麼關係
     void func(int i, int j)
    {
        cout<<"Child:void func(int i, int j)"<<" "<<i + j<<endl;
    }

    //此處3個引數的,和子類func函式是什麼關係
    void func(int i, int j, int k)
    {
        cout<<"Child:void func(int i, int j, int k)"<<" "<<i + j + k<<endl;
    }
};

void run01(Parent01* p)
{
    p->func(1, 2);
}

int main()
{
    /*
    Parent01 p;

    p.func();
    p.func(1);
    p.func(1, 2);
    */

    Child01 c;
    //c.Parent01::abcd(); //這個函式是從父類中繼承而來 可以使用。。。
    //子類和父類有相同的名字(變數名字或者是函式名字的時,子類名字覆蓋父類名字,如果想使用父類的資源,需要加::)
    //c.Parent01::func(); //問題1 這個函式是從父類中繼承而來,為什麼這個地方不能使用
    c.Parent01::func(); //問題1
    //c.func(1, 2);
        /*
    run01(&p);
    run01(&c);
    */
    return 0;
}

//問題1:child物件繼承父類物件的func,請問這句話能執行嗎?why
//c.func(); 

//1子類裡面的func無法過載父類裡面的func 
//2當父類和子類有相同的函式名、變數名出現,發生名稱覆蓋
//3//c.Parent::func();
//問題2 子類的兩個func和父類裡的三個func函式是什麼關係?

相關文章