1. 程式人生 > >C++中重寫過載重定義的區別

C++中重寫過載重定義的區別

創建於 2012-05-23

遷移自個人的百度空間

--------------------------------

過載overload:是函式名相同,引數列表不同 過載只是在類的內部存在。但是不能靠返回型別來判斷。

重寫override:也叫做覆蓋。子類重新定義父類中有相同名稱和引數的虛擬函式。函式特徵相同。但是具體實現不同,主要是在繼承關係中出現的 。

重寫需要注意:

1 被重寫的函式不能是static的。必須是virtual的

2 重寫函式必須有相同的型別,名稱和引數列表

3 重寫函式的訪問修飾符可以不同。儘管virtual是private的,派生類中重寫改寫為public,protected也是可以的

 

重定義 (redefining)也叫做隱藏:

子類重新定義父類中有相同名稱的非虛擬函式 ( 引數列表可以不同 ) 。

如果一個類,存在和父類相同的函式,那麼,這個類將會覆蓋其父類的方法,除非你在呼叫的時候,強制轉換為父類型別,否則試圖對子類和父類做類似過載的呼叫是不能成功的。 

class Base
{
    private:
        virtual void display() { cout<<"Base display()"<<endl; }
        void say(){ cout<<"Base say()"<<endl; }
    public:
        void exec(){ display(); say(); }
        void f1(string a) { cout<<"Base f1(string)"<<endl; }
        void f1(int a) { cout<<"Base f1(int)"<<endl; } //overload,兩個f1函式在Base類的內部被過載
};

class DeriveA:public Base
{
    public:
        void display() { cout<<"DeriveA display()"<<endl; } //override,基類中display為虛擬函式,故此處為重寫
        void f1(int a,int b) { cout<<"DeriveA f1(int,int)"<<endl; } //redefining,f1函式在Base類中不為虛擬函式,故此處為重定義
        void say() { cout<<"DeriveA say()"<<endl; } //redefining,同上
};


class DeriveB:public Base
{
    public:
    void f1(int a) { cout<<"DeriveB f1(int)"<<endl; } //redefining,重定義
};


int main(){
    DeriveA a;
    Base *b=&a;
    b->exec(); 
    //display():version of DeriveA call(polymorphism) 
    //say():version of Base called(allways)b裡邊的函式display被A類覆蓋,但是say還是自己的。

    a.exec(); //same result as last statement   
    a.say();
    DeriveB c;
    c.f1(1); //version of DeriveB called
}

執行結果:

綜上所述,總結如下:

1 成員函式過載特徵:
   a 相同的範圍(在同一個類中)

   b 函式名字相同

   c 引數不同

   d virtual關鍵字可有可無

2 重寫(覆蓋)是指派生類函式覆蓋基類函式,特徵是:

   a 不同的範圍,分別位於基類和派生類中

   b 函式的名字相同

   c 引數相同

   d 基類函式必須有virtual關鍵字

3 重定義(隱藏)是指派生類的函式遮蔽了與其同名的基類函式,規則如下:

   a 如果派生類的函式和基類的函式同名,但是引數不同,此時,不管有無virtual,基類的函式被隱藏。

   b 如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有vitual關鍵字,此時,基類的函式被隱藏。