Dynamic_cast未显示正确的对象类型

时间:2017-08-16 21:42:43

标签: c++ dynamic-cast

我花了很多时间试图弄清楚为什么我的代码在运行之后显示“Derived3”而我根本无法理解它。根据我在这里阅读的许多帖子,dynamic_cast应该以某种方式说出指针(在这种情况下是b)是否(在这种情况下)Derived2。但是,它传递了条件,当它应该从Derived2类打印出display()函数时,它会奇怪地显示Derived3类中的那个。我只是想知道为什么程序显示“Derived 3”而不显示任何内容,因为b指针显然没有指向Derived2对象。

#include <iostream>

using namespace std;

class Base
{
    int b;
    public:
    virtual void display()
    {
        cout<<"Base"<<endl;
    }
};

class Derived: virtual public Base{
public:
    void display()
    {
        cout<<"Derived"<<endl;
    }
};

class Derived2: virtual public Base{
public:
    void display()
    {
        cout<<"Derived 2"<<endl;
    }
};

class Derived3:public Derived,public Derived2{
public:
    void display()
    {
        cout<<"Derived 3"<<endl;
    }
};

int main()
{
    Base *b = new Derived3();
    Derived2 *aux = dynamic_cast<Derived2*>(b);
    if(aux)
    {
        aux->display();
    }

    return 0;
}

然而,在稍微编辑代码之后,它可以正常工作。

#include <iostream>

using namespace std;

class Base
{
    int b;
    public:
    virtual void display()
    {
        cout<<"Base"<<endl;
    }
};

class Derived: public Base{
public:
    void display()
    {
        cout<<"Derived"<<endl;
    }
};

class Derived2: public Base{
public:
    void display()
    {
        cout<<"Derived 2"<<endl;
    }
};

class Derived3:public Base{
public:
    void display()
    {
        cout<<"Derived 3"<<endl;
    }
};

int main()
{
    Base *b = new Derived3();
    Derived2 *aux = dynamic_cast<Derived2*>(b);
    if(aux)
    {
        aux->display();
    }

    return 0;
}

2 个答案:

答案 0 :(得分:3)

继承是“Is-a”的关系。

每个 ...//for comprehension logic } yield (ticketList, eventList) } .filter( (i: TicketList, k: List[SummaryByEvent]) => i.tickets.flatMap(x => List(x.event)).diff(k.flatMap(x => List(x.event))) // returns List[Event] .filter(p => p.dynamicAttribute.get.get("TICKETHOLDER_ONLY") == Some("true")) // also returns List[Event] 都是DerivedDerived。按照该模式,每个Base同时为Derived3Derived3Derived2Derived

因此,演员失败是没有意义的。

然后输出最终是Base上正常虚函数调用的结果。这与最简单的继承示例没有什么不同,例如在这个片段中:

Derived2*

如果您有指向某个基类的指针或引用,则虚函数调用将解析为调用它的对象的实际类型。在您的情况下,这是#include <iostream> struct A { virtual void fun() const { std::cout << 'A'; } }; struct B : A { void fun() const { std::cout << 'B'; } }; int main () { const A &a = B(); a.fun(); // prints 'B' } 指向类型为Derived2*的子类,因此在后者中查找该函数。

请记住,Derived3只会更改指针的类型,而不会更改它指向的对象的类型!

答案 1 :(得分:0)

  

然而,它传递了条件,当它应该从Derived2类打印出display()函数时,它奇怪地显示了Derived3类中的那个。

这是因为动态调度。请记住,display()被声明为virtual成员函数。它仍然是所有派生类的virtual成员函数。

即使您将指针从Base*转换为Derived*,基础对象仍然是Derived3。因此,动态调度机制调用Derived3::display()

如果你使用:

,也会调用

Derived3::display()

Base *b = new Derived3();
b->display();