简体   繁体   中英

dynamic_cast fails when cast a base class to derived class

I have two classes, base class and a derived class. The base class has a virtual method.

Here is my test example:

class Base
{
public:
    virtual void Hello() { cout << "-> Hello Base" << endl; }
};

class Derived: public Base
{
public:
    void Hello() { cout << "-> Hello Derived" << endl; }
};

int main()
{
    Base *mBase = new Base;
    // something to do 
    ....

    Derived *mDerived = dynamic_cast<Derived*>(mBase);
    mDerived->Hello();

    return 0;
}

I'm looking to use the Hello() method of the class derived after the cast of mBase to mDerived .

But the problem is that when I try to use dynamic_cast it will crash the application, if not if I use reinterpret_cast the Hello() method of the Base class will be called.

Result in the case dynamic_cast :

Segmentation fault (core dumped)

Result in the case dynamic_cast :

-> Hello Base

dynamic_cast fails when cast a base class to derived class

This is what is supposed to happen. When you dynamic cast a pointer to an object whose dynamic type is not the casted type, then you get a null pointer as the result.

In your example, you indirect through the null pointer and attempt to call a member function which results in undefined behaviour.

When using dynamic cast, you must always check whether you got null or not.

if I use reinterpret_cast...

Then the behaviour will still be undefined because you'll be indirecting through a pointer to an object that does not exist. Unless you create an instance of the derived class, you cannot call its non static member function.

You can convert a base instance into a derived one like this for example:

Base b;
Derived d = b;

What happens is that the base sub object of the derived instance is copy initialised from b .

Two problems in your code: Base should have a virtual destructor so Dervied isntances can be properly destructed via a pointer to Base . Then, you are not constructing an object of type Derived , so the cast cannot succeed. dynamic_cast can fail and you should check its result for not being a nullptr . Also you forgot to delete the created object.

If you do create an instance of type Derived your code works:

#include <iostream>
using std::cout;
using std::endl;

class Base
{
public:
    virtual void Hello() { cout << "-> Hello Base" << endl; }
    virtual ~Base(){}
};

class Derived: public Base
{
public:
    void Hello() { cout << "-> Hello Derived" << endl; }
};

int main()
{
    Base* mBase = new Derived;
    Derived *mDerived = dynamic_cast<Derived*>(mBase);
    if (mDerived) mDerived->Hello();
    delete mBase;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM