1

我对将指向基类对象的指针转换为派生类的指针感到困惑。请检查以下代码:

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

结果是:

  • 我是基地的一个虚拟功能。
  • 我是派生类中的一个函数。
  • 谁能帮我解释为什么要d1->print()打印“我是基地的虚拟功能。”?

    #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,而是指向 a 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 incb指向的虚函数表中查找。由于cv是 a base,表将是 的base,其中包含print具有base::print实现的函数。这就是为什么调用该函数的原因。

    于 2012-11-21T00:35:47.777 回答
    0

    d1 是一个 derivate_class 指针,但它实际指向的数据 (cb) 是 base 类型。由于 print() 是虚拟的,因此调用是动态解析的,因此它将在虚拟函数表中找到 base 的实现,而不是 derivate_class 的。

    于 2012-11-21T00:43:45.783 回答