22

私は、自分のコードを警告なしでコンパイルする必要がある人の 1 人です。通常、私はコンパイラを尊重し、警告が表示された場合は、コードを少し修正する必要があるというサインと見なします。与えられた警告を無視するようにコンパイラーに指示しなければならない場合、私は少しひきつります。

しかし、これは私が回避できないようであり、私が言えることから、私は何も「悪い」ことをしていません. これは悪いデザインだと思う人はいますか?特に厄介な点は見当たりませんが (「邪悪なダイヤモンド」を除いて)、完全に有効で有用なコードです。しかし、(MSVC で) レベル 2 の警告が生成されます!

class IFoo
{
public:
    virtual void foo() = 0;
};

class Bar : public virtual IFoo
{
public:
    virtual void foo() { std::cout << "Hello, world!"; }
};

class Baz : public virtual IFoo
{

};

class Quux : public Bar, public Baz
{

};

Quux オブジェクトを作成すると、Bar::foo 実装を呼び出すことが期待されます。MSVC は非常に役に立ちます。あいまいさが足りないと警告してくれます。

警告 C4250: 'Quux': 優性経由で 'Bar::Bar::foo' を継承します

これで、プラグマを使用してこの警告をオフにできることがわかりましたが、それは私がここで尋ねようとしている質問ではありません。ここでコンパイラに耳を傾ける必要がある理由はありますか、それとも非常に熱心な警告ですか?

4

3 に答える 3

12

仮想継承を実行する場合、最も派生したクラスのすべてのメンバーを明示的にオーバーライドしないことはお勧めできません。それ以外の場合は、仮想ベースから継承するベース クラスの 1 つが変更されたときに、コードが悲惨な死に方をすることを要求しています。これには積極的な問題はありません。プログラムがクラッシュしたり、そのようなことはありませんが、保守性は悪い考えです。バージョンを呼び出したい場合はBar::foo、 で委任するだけですQuux::foo

于 2011-08-15T22:47:43.070 に答える
2

コードの実行可能性に関する限り、Bar が の主要な実装であることを思い出してくださいfoo。これは単に通知するためのものであり、実際には警告ではないため、デバッグ中に問題があると思われる場合Bazは、髪を引っ張らないでください :)。

于 2011-08-15T22:47:55.833 に答える
1

あなたが書いていない理由はありますか:

class Quux : public Bar, public Baz
{
    using Bar::foo;
};

これにより、脆弱性がなく、同じレベルの再利用が可能になります。

于 2011-11-23T05:22:35.327 に答える