Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dynamic_cast and polymorphism

This is my first question on this site, so feel free to highlight any problems with my word choice, question structure, etc.

Recently, I started to use dynamic_cast when dealing with polymorphism, and I've read that dynamic_cast doesn't create another instance of the class but instead it creates another instance of the pointer to the object.

While testing dynamic_cast, I encountered this problem. Here is the code:

//main.cpp

#include <iostream>

class Base{
public:
    int BaseNum;
    virtual void BaseFunction(){};
};

class Derived : public Base{
public:
    int DerivedNum; 
    virtual void DerivedFunction(){};
};

int main(){

    Base * ptrBase = new Base;
    ptrBase->BaseNum = 0;
    Derived * ptrDerived = dynamic_cast<Derived *>(ptrBase);
    ptrDerived->DerivedNum = 1;

    std::cout << ptrBase->BaseNum << ptrDerived->DerivedNum << std::endl;

    system("pause");
    return 0;
}

The program crashed in the line:

ptrDerived->DerivedNum = 1;

While debugging, it said "unable to read memory". My conclusion was that I can't downcast if the original memory allocation was reserved for a class that was higher in the hierarchy, but I think I might be wrong.

Where did the code go wrong?

like image 854
Ediac Avatar asked Apr 20 '15 22:04

Ediac


2 Answers

dynamic_cast locates the requested class type within the specified object and returns a pointer/reference to that section of the object. If it cannot be found, a NULL is returned for a pointer cast, and a std::bad_cast exception is thrown for a reference cast. In your example, it fails because ptrBase is not pointing at an object that is an instance of the Derived class, so there is no Derived section within the object to return a pointer to, so it returns NULL. You need to change this:

Base * ptrBase = new Base;

To this instead:

Base * ptrBase = new Derived;
like image 143
Remy Lebeau Avatar answered Sep 20 '22 13:09

Remy Lebeau


Your problem is that you are using dynamic cast backwards.

If you did

   Base *ptrBase = new Derived ;

Then it would work.

Derived IS A Base. Base IS NOT A Derived.

like image 37
user3344003 Avatar answered Sep 20 '22 13:09

user3344003