#include <iostream>
#include <memory>
{
{
   public:
    void printName() { std::cout << 
"printName: Foo" << std::endl; }
 };
{
   public:
    virtual void printName() { std::cout << 
"printName: BarBase" << std::endl; }
 };
class Bar : public BarBase
{
   public:
    void printName()
 override { std::cout << 
"class: Bar" << std::endl; }
     {
        std::cout << "specificBarMethod: reached." << std::endl;
    }
};
}  
{
    std::cout << "RTTI Foo (static): " << id_foo->className << std::endl;
    
    Bar::Ptr pBar = std::make_shared<Bar>();
     pBar->printName();
    pBase->printName();
    std::cout << 
"Is Foo?   => " << (
IS_DERIVED(*pObj, 
Foo) ? 
"Yes\n" : 
"No\n");
    std::cout << "Is BarBase? => "
    std::cout << 
"Is Bar?  => " << (
IS_DERIVED(*pObj, 
Bar) ? 
"Yes\n" : 
"No\n");
    {
        pBar2->specificBarMethod();
    }
}
{
    
    {
        
    }
}
{
    
    {
        for (const auto& cl : allClasses)
        {
            std::cout << "Known class: " << cl->className << ", children of "
                      << (cl->getBaseClass ? cl->getBaseClass()->className
                                           : "(none)")
                      << std::endl;
        }
    }
    
    {
        {
            pBar->specificBarMethod();
        }
    }
}
{
    try
    {
        return 0;
    }
    catch (const std::exception& e)
    {
        return -1;
    }
}