2011-06-18 30 views
11

關鍵字虛擬在重寫某個方法時做什麼?我沒有使用它,一切正常。覆蓋某個方法時,virtual關鍵字意味着什麼?

每個編譯器在這方面的行爲是否相同?

我應該使用它嗎?

+0

[C++ Virtual/Pure Virtual Explained]的可能重複(http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained) –

+0

@Harald:Nope。不同的主題。 – Xeo

+0

但我在問關於那個關鍵字的用法。不是關於抽象的虛擬方法。 – kravemir

回答

11

不能覆蓋的成員函數沒有它。

你只能隱藏其中之一。

struct Base { 
    void foo() {} 
}; 

struct Derived : Base { 
    void foo() {} 
}; 

Derived::foo覆蓋Base::foo;它只是隱藏它,因爲它具有相同的名稱,如下列:

Derived d; 
d.foo(); 

調用Derived::foo

virtual使多態性,這樣你實際上覆蓋功能:

struct Base { 
    virtual void foo() {} 
}; 

struct Derived : Base { 
    virtual void foo() {} // * second `virtual` is optional, but clearest 
}; 

Derived d; 
Base& b = d; 
b.foo(); 

這將調用Derived::foo,因爲這個現在覆蓋Base::foo —你的對象是多態的。

(您也使用引用或指針對於這一點,由於the slicing problem。)


  • Derived::foo不需要重複virtual關鍵字,因爲Base::foo已經使用它。這是由標準保證的,你可以依靠它。但是,有些人認爲最好保持清晰。
+2

我知道虛擬是必要的,當聲明方法可以被覆蓋。我在重寫方法時詢問了有關使用此關鍵字的問題,而不是聲明。 – kravemir

+1

@Miro:我沒有關注。通過聲明另一個覆蓋它的函數來覆蓋函數。無論如何,至少我的最後一段會回答你的問題。 –

8

A virtual在基類中的方法將級聯通過層次結構,使每個具有相同簽名的子類方法也是virtual

class Base{ 
public: 
    virtual void foo(){} 
}; 

class Derived1 : public Base{ 
public: 
    virtual void foo(){} // fine, but 'virtual' is no needed 
}; 

class Derived2 : public Base{ 
public: 
    void foo(){} // also fine, implicitly 'virtual' 
}; 

儘管如果僅用於文檔目的,我會推薦編寫virtual

5

當一個函數是虛擬的時候,它在整個層次結構中保持虛擬,無論你是否每次明確地指定它是虛擬的。覆蓋方法時,使用虛擬爲了更加明確的 - 沒有其他的區別:)

class A 
{ 
    virtual void f() 
    { 
     /*...*/ 
    }; 
}; 

class B:public A; 
{ 
    virtual void f() //same as just void f() 
    { 
     /*...*/ 
    }; 
};