1

基本クラスオブジェクトへのポインターを派生クラスのポインターに変換することに混乱しています。次のコードを確認してください。

derivate_class *d1 = (derivate_class*)cb;
d1->print();
d1->print1();

結果は次のとおりです。

  • I は base の仮想関数です。
  • 私は派生クラスの関数です。
  • d1->print()「I'm a virtual function in base.」と出力する理由を説明できる人はいますか?

    #include <iostream>
    using namespace std;
    
    class base
    {
    public:
        virtual void print()
        {
            cout << "I'm a virtual function in base." << endl;
        }
    };
    
    class derivate_class : public  base
    {
    public:
        void print()
        {
            cout << "I rewrite the virtual function in base." << endl;
        }
    
        void print1()
        {   
            cout << "I'm a function in derivate class." << endl;
        }
    };
    
    int main()
    {
        base* b = new base();
        derivate_class *d = new derivate_class();
        b->print();
        d->print1();
        base* cb = b;
        b = d;
        b->print();
        cout << "*********************" << endl;
    
        derivate_class *d1 = (derivate_class*)cb;
        d1->print();
        d1->print1();
    
        system("pause");
        return 0; 
    }
    
    4

    2 に答える 2

    3

    UBなので何でもありです。

    しかし、ここに説明があります:d1実際には a を指すのではなく、 を指しderivate_classますbase

    base* b = new base();
    //...
    base* cb = b;
    derivate_class *d1 = (derivate_class*)cb;
    d1->print();
    d1->print1();
    

    呼び出しはポインターを介して行われ、メソッドが であるため、呼び出しは動的に解決されますvirtual

    print1そうではなくvirtual、呼び出しは静的に解決されます。printただしvirtual、 であるため、最も派生した型の実装が呼び出されます。しかし、最も派生した型は実際baseにはこの場合です。

    内部的には、メソッドprintは vfptr がcb指す仮想関数テーブルで検索されます。cvは であるためbase、テーブルは のテーブルになり、実装さbaseれた関数が含まれます。そのため、関数が呼び出されます。printbase::print

    于 2012-11-21T00:35:47.777 に答える
    0

    d1 は derivate_class ポインターですが、実際に指しているデータ (cb) は base 型です。print() は仮想であるため、呼び出しは動的に解決され、derivate_class の代わりに仮想関数テーブルで base の実装が検出されます。

    于 2012-11-21T00:43:45.783 に答える