1. 程式人生 > >C++函式過載、重寫與重定義

C++函式過載、重寫與重定義

  • 過載:同一個類中(不一定是在類中),定義了多個同名的函式,這些函式的引數列表(引數個數,引數類型別)不完全相同,這是函式的過載。函式的返回值型別不能作為是否是過載的判斷依據,因為返回值型別可以捨棄、可以自動轉換等。
  • 重寫:類的繼承裡,子類裡含有與父類裡同名的虛擬函式,函式名、函式返回值型別和引數列表必須相同,許可權可以不同。如果返回值型別或者引數列表不同,這是子類方法的重定義,即使加了virtual也不會體現出多型。
  • 重定義:父類和子類中有相同名稱的非虛擬函式,返回值型別、引數列表可以不同。子類物件呼叫該同名方法時,子類方法將覆蓋父類方法。

程式1:方法的過載

class A
{
public
: A(){} ~A(){} int getMax(int a,int b){return a>b?a:b;}//1 double getMax(int a,int b){return a>b?a:b;}//2 double getMax(double a,double b){return a>b?a:b;}//3 };

上面的程式中,方法1和方法3是函式的過載(引數列表不同);但是方法2不是,因為與方法1比起來只是返回值不同,而返回值不能作為函式過載的判斷,在編譯階段會出錯。

程式2:方法的重定義

class A
{
public:
    A
(){} ~A(){} void show(){cout<<"A::show()"<<endl;} }; class B:public A { public: B(){} ~B(){} void show(){cout<<"B::show()"<<endl;} }; int main() { A *a = new A(); B *b = new B(); A *c = new B(); a->show(); b->show(); c->show(); system("pause"
); return 0; }

這裡寫圖片描述
上面的程式中,show()是普通的成員函式,子類B重新定義了show(),因此b->show()的結果是“B::show()”。如果B中沒有重新定義show(),那b->show()的結果是“A::show()”。在類的多型中,基類指標c可以指向子類物件,由於show()不是虛擬函式,因此呼叫show時將執行指標本身的型別的show(),即A::show()。
如果我修改B中show()的返回值型別或者引數列表:

class B:public A
{
public:
    B(){}
    ~B(){}
    int show(int a){cout<<"B::show()"<<endl; return 1;}
};

那麼下面程式中b->show()將報錯,因為b中show覆蓋了A中的show方法。
這裡寫圖片描述

程式3:方法的重寫

class A
{
public:
    A(){}
    ~A(){}
    virtual void show(){cout<<"A::show()"<<endl;}
    virtual void print(){cout<<"A::print()"<<endl;}
    virtual void eat(){cout<<"A::eat()"<<endl;}
};

class B:public A
{
public:
    B(){}
    ~B(){}
    virtual void show(){cout<<"B::show()"<<endl; }
    virtual int print(){cout<<"B::print()"<<endl;}
    virtual void eat(int a){cout<<"B::eat()"<<endl;}
};

上面程式定義了基類A和子類B,並且定義了3個虛擬函式show(), print() 和eat()。

  • show():是重寫,返回型別、引數列表相同;
  • print():不是重寫,返回型別不同;
  • eat():是不是重寫??反正基類指標派生類物件時,不會呼叫派生類的eat()方法。
    刪掉兩個類裡面的print()方法定義,執行下面程式:
int main()
{
    A *c = new B();
    c->show();
    c->eat();

    system("pause");
    return 0;
}

這裡寫圖片描述
可以看到,show函式是虛擬函式,並且在A和B中返回值型別、引數列表相同,是重寫,體現了類的多型。而eat函式雖然也是虛擬函式,但是並沒有呼叫“指向物件的型別”的方法。