Search code examples
c++boostpolymorphismshared-ptrtypeinfo

Get type_info for subclass when using shared_ptr


I have the following minimal example code. I want to be able to determine the Derived class in my Application::HandleEvent method.

The Application class will ultimately contain a map which maps type_info to a handler function (I know how to do this using operator<) to route Events to their specific handlers.

There is no issue doing this using polymorphism with raw pointers, but I'm unable to do this if shared_ptrs are brought into the mix.

It always reports that the type_info is that of the base class, whether I use type_info of the shared_ptr (not a big surprise the smart pointers are not polymorphically related) or type_info of the pointed to class using .get().

Is this possible? I'm not looking for a solution whereby I define a handler method in the event subclass itself.

#include <typeinfo>
#include <iostream>

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

class Event
{
    public:
    virtual ~Event(){};
};

class SpecificEvent1 : public Event
{};

class SpecificEvent2 : public Event
{};

class Application
{
    public: 
    void HandleEvent(boost::shared_ptr<Event> e)
    {
        std::cout << typeid(e.get()).name() << "\n";
        std::cout << typeid(e).name() << "\n";
    }
};

int main(int, char**)
{
    Application app;

    boost::shared_ptr<SpecificEvent1> se1 = boost::make_shared<SpecificEvent1>();
    boost::shared_ptr<SpecificEvent2> se2 = boost::make_shared<SpecificEvent2>();

    app.HandleEvent(se1);
    app.HandleEvent(se2);
}

Solution

  • When you use typeid on a pointer, you get information about the pointer, not the underlying object. To get information about the underlying object corresponding to a polymorphic pointer, use a reference, i.e. dereference the pointer

    Instead of

    std::cout << typeid(e.get()).name() << "\n";
    

    Use

    std::cout << typeid(*e).name() << "\n";