2011-06-18 9 views
11

仮想というキーワードは、メソッドをオーバーライドするときに何をしますか?私はそれを使用していないとすべてうまく動作します。メソッドをオーバーライドするとき、仮想キーワードはどういう意味ですか?

この点に関して、すべてのコンパイラが同じように動作しますか?

私はそれを使うべきかどうか?

+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(); 

この今オーバーライドBase::foo —あなたのオブジェクトが多型であるため、これは、Derived::fooを呼び出します。

(また が原因 the slicing problemに、このための参照やポインタを使用する必要があります。)
  • Derived::foo

    Base::fooはすでにそれを使用しているためvirtualキーワードを繰り返す必要はありません。これは標準によって保証されており、あなたはそれに頼ることができます。しかし、明確にするためにそれを保つのが最善と考える人もいます。
+2

私は、オーバーライド可能なメソッドを宣言するときに仮想が必要であることを知っています。私は宣言しないで、メソッドをオーバーライドするときにこのキーワードを使うことについて尋ねました。 – kravemir

+1

@Miro:私は従いません。関数をオーバーライドするには、関数をオーバーライドする関数を宣言します。いずれにせよ、少なくとも私の最後の段落はあなたの質問に答えます。 –

8

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() 
    { 
     /*...*/ 
    }; 
}; 
関連する問題