4

仮想継承に関してVisualStudio2008に問題があります。

次の例を考えてみましょう。

#include<iostream>

class Print {
    public:

    Print (const char * name) {
        std::cout << name << std::endl;
    }
};

class Base : public virtual Print {
    public:

    Base () : Print("Base") {}
};

class A : public Base {
    public:

    A () : Print("A") {}
};

class B : public A {
    public:

    B () : Print("B") {}
};

int main (int argc, char** argv) {
    A a; // should print "A"
    B b; // should print "B"
    return 0;
}

Linuxマシンでgccを使用すると、このコードは問題なくコンパイルされます。しかし、Visual Studioを使用してWindowsで同じものをビルドしようとすると、「エラーC2614:'B':不正なメンバーの初期化:'印刷'はベースまたはメンバーではありません」というエラーメッセージが表示されてコンパイルが失敗します。

なぜこれが機能しないのですか?

4

2 に答える 2

4

標準[class.base.init]から:「mem-initializer-idがコンストラクターのクラスの非静的データメンバーまたはそのクラスの直接または仮想ベースを指定しない限り、mem-initializerは不正な形式です。」

Print明らかに、gccはあなたのケースを非直接のように合法であると解釈しますが、の仮想ベースですがB、MSVC2008はPrintの仮想ベースとしては認識しませんB-非仮想ベースの仮想ベースのみ。(ちなみに、あなたの例はVS2005でコンパイルされているので、動作が驚くほど変化しています。)

私は正しいとの解釈に傾倒しgccます(そうでなければ、「直接ベース」という言い回しで十分でした)。

この問題を回避するには、からB仮想的に派生させることができますPrintPrintすでに仮想ベースであるため、クラスレイアウトやベースクラスサブオブジェクトAの数に全体的な影響はありません。Print

于 2009-09-17T07:31:57.773 に答える
0

どのバージョンのVisualStudioを使用していますか?あなたが投稿したコードは、VC 9(具体的には15.00.21022.08)、VC 6、およびその他のいくつかのコンパイラーで問題なく動作します。

class BVisual Studioで誤って次のように表示されないことを確認しますか?

class B {  //  note: no base class
    public:

    B () : Print("B") {}
};
于 2009-09-17T07:35:23.937 に答える