1

このプログラムでは:

    class Top
    {
            public:
            int a;
    };

    class Left : virtual public Top
    {
            public:
            int b;
    };

    class Right : virtual public Top
    {
            public:
            int c;
    };

    class Bottom : public Left, public Right
    {
            public:
            int d;
    };

    class AnotherBottom : public Left, public Right
    {
            public:
            int e;
            int f;
    };

    int main()
    {
        Bottom* bottom1 = new Bottom();
        AnotherBottom* bottom2 = new AnotherBottom();
        Top* top1 = bottom1;
        Top* top2 = bottom2;
        Left* left = static_cast<Left*>(top1);
        return 0;
    }

私はこのプログラムに関していくつかの疑問を持っています:

static_cast を実行すると、コンパイラはエラーを出します

error: cannot convert from base ‘Top’ to derived type ‘Left’ via virtual base ‘Top

動的キャストでもエラーが発生します

error: cannot dynamic_cast ‘top1’ (of type ‘class Top*’) to type ‘class Left*’ (source type is not polymorphic)

そのため、Top クラスに仮想デストラクタを追加すると、ポリモーフィックになり、動的キャストが可能になります。

なぜこれが起こっているのか理解できません。

4

1 に答える 1

2

キャストを静的に行うことはできません。Top から (場合によっては複数回) および Left から仮想的に継承するクラスを想像してください。レイアウトは、そのクラスの詳細によって異なります。そのため、Top インスタンスがどこにあるかだけを考えれば、Left インスタンスのデータがどこにあるかを特定する既知の方法は 1 つもありません。

解決策は、情報をオブジェクト自体に (通常は vtable の一部として) 埋め込んでから、動的に計算を行うことです。したがって、「私は実際には Left のインスタンスであり、Top ベース インスタンスは this ポインターが指す場所から 12 バイトです」というデータを含めることができます。

しかし、C++ はすべてのオブジェクトがその情報を強制的に保持することを望んでいません。とにかくvtableを持つ必要があるものである(そしてこれは偶然ではありません)ポリモーフィッククラスによってのみ格納される必要があります。

于 2012-05-12T20:22:14.857 に答える