2011-07-22 36 views

回答

10

不同之處在於它不是使用它的基礎,而是派生的。

class Base { 
    virtual void foo() = 0; 
}; 
class Derived : Base { 
    void foo() {} 
    // Still virtual because it's virtual in base- no way to "un-virtual" it 

    virtual void foo() final {} 
    // Now un-overridable. 
}; 

認爲它不是防止覆蓋,而是防止「更多」覆蓋。

+0

謝謝!我不清楚,虛擬獲得了整個層次結構。 –

1

當我第一次碰到用結合的final關鍵字來在C virtual ++,我想知道同樣的事情:

如果聲明的方法virtual使得它繼承和重寫,並宣佈一個方法final防止該方法被覆蓋,不聲明方法兩個形成矛盾?

我認爲目前的accepted answer這個問題很好,但是我想基於我發現的這個問題來增加一點。

考慮下面的類:

class A { 
    public: 
     void hide_me(); 
     virtual void override_me(); 
     virtual void cant_override_me() final; 
}; 

認識到的重要一點是,這三個方法聲明是完全不同的,並意味着不同的事情。

第一:

void hide_me(); 

是非虛擬因此,根據定義,不能被重寫。

第三種:

virtual void cant_override_me() final; 

被聲明final,並且因此不能被重寫,也通過定義。

所不同的是,由於hide_me非虛擬的,壓倒一切的是unapplicable,而你能想到的cant_override_me資格被覆蓋(因爲它是virtual也已覆蓋禁用由於final修飾符。換句話說,覆蓋不適用於未聲明爲virtual的方法,但它適用於virtual方法,如果它們也被聲明爲final,則不能覆蓋它們。

現在考慮一個子類:

class B: public A { 
    public: 
     void hide_me(); // this hide's A's definition of "hide_me()"; this is not overriding. 
     void override_me(); // implicit "virtual" 
     //void cant_override_me(); // implicit "virtual"; compilation fails 
}; 

可以重新定義爲hide_me()B,但是這僅僅是超載或hiding,因此函數名。 B仍然可以通過A::hide_me()訪問Ahide_me方法,但是參考B的其他人聲明爲B,即連接:my_b->A::hide_me()

B *my_b = new B(); 

必須訪問A的現在隱藏的hide_me定義。

不能提供cant_override_me()B重新定義。

作爲一個完整的例子,這裏是該計劃的一個輕微的重新定義,以幫助舉例說明這是怎麼回事:

#include <cstdio>  
class A { 
    public: 
     inline void hide_me() { 
      printf("a hide_me\n"); 
     } 
     virtual void override_me(); 
     virtual void cant_override_me() final; 
}; 

class B: public A { 
    public: 
     inline void hide_me() { 
      printf("b hide_me\n"); 
     } 
     void override_me(); 
     inline void foo() { 
      A::hide_me(); 
     } 
     // can't override cant_override_me 
}; 

void A::override_me() { 
    printf("a override_me\n"); 
} 

void A::cant_override_me() { 
    printf("a cant_override_me\n"); 
} 

void B::override_me() { 
    printf("b override_me\n"); 
} 

int main (int argc, char *argv[]) { 
    A *a = new A(); 
    A *ab = new B(); 
    B *b = new B(); 

    a->hide_me(); 
    ab->hide_me(); 
    b->hide_me(); 
    b->A::hide_me(); 

    printf("---\n"); 

    a->override_me(); 
    ab->override_me(); 
    b->override_me(); 
    b->A::override_me(); 
} 

方案產出

a hide_me 
a hide_me 
b hide_me 
a hide_me 
--- 
a override_me 
b override_me 
b override_me 
a override_me