4

いくつかの古いコードを調べているときに、次のようなものに出くわしました。

class Base
{
public:
    virtual int Func();
    ...
};

class Derived : public Base
{
public:
    int Func(); // Missing 'virtual' qualifier
    ...
};

コードは警告なし (レベル 4) で正常にコンパイルされ (MS VS2008)、期待どおりに動作しFuncます。派生クラスに仮想修飾子がありませんが、仮想です。さて、混乱を招く以外に、このコードには危険がありますか、virtualそれとも修飾子を追加してすべてを変更する必要がありますか?

4

4 に答える 4

10

これvirtualは、派生クラスのすべてのオーバーライド関数に適用されます。キーワードを追加することの唯一の本当の利点は、Derived クラスの定義を何気なく見ている人が、それFuncが仮想であることをすぐに理解できることを示すことです。

Derived を拡張するクラスでさえ、仮想 Func メソッドを持ちます。

参照: MSDN の仮想関数。ページを下にスクロールしてご覧ください

virtualキーワードは、派生クラスでオーバーライド関数を宣言するときに使用できますが、不要です。仮想関数のオーバーライドは常に仮想です。

于 2008-12-04T12:33:51.137 に答える
2

オーバーライド関数 virtual を宣言する必要がないという興味深い結果は次のとおりです。

template <typename Base>
struct Derived : Base
{
    void f();
};

Derived の f が仮想になるかどうかは、Derived が正しい署名の仮想関数 f を持つ Base でインスタンス化されるかどうかによって異なります。

于 2008-12-04T12:49:29.250 に答える
0

この方法に従うことの危険性の1つは、仮想化を目的とした関数に仮想キーワードが必要であることに人々が気付かない可能性があることです。これは、非仮想関数の概念がない言語(Java、REALbasicなど)から来ている人である可能性が最も高いです。当然の結果として、関数は非仮想であると想定されているため、仮想が意図的に省略された時期を知ることはできません。

一部のコード分析ツールも、継承された仮想性を取得するのに十分なほど賢くないのではないかと思います。

于 2009-01-18T02:09:50.330 に答える
0

仕様に準拠していない非常に古い C++ コンパイラでは、すべてのサブクラスに virtual を設定する必要があると誰かが言ったことがあります。それはもう問題ではありません。

于 2008-12-04T12:37:00.040 に答える