#include <iostream>
#include <map>
#include <typeinfo>
#include <typeindex>
#include <string>

class Base {
public:
    virtual ~Base() {}
};
    
class Manager
{
private:
    static std::map<std::type_index, Base*> m_instances;
    
public:
    template<typename T>
    static void addInstance(Base *inst) {
        m_instances[std::type_index(typeid(T))] = inst;
    }
    
    template<typename T>
    static void removeInstance() {
        auto iter = m_instances.find(std::type_index(typeid(T)));
        if (iter != m_instances.end())
            m_instances.erase(iter);
    }
    
    template<typename T>
    static T* getInstance() {        
        auto iter = m_instances.find(std::type_index(typeid(T)));
        if (iter != m_instances.end())
            return static_cast<T*>(iter->second);
        return nullptr;
    }
};
    
template<class Derived>
class A : public Base
{
public:
    A() {
        Manager::addInstance<Derived>(this);
    }
    
    ~A() {
        Manager::removeInstance<Derived>();
    }
    
    static Derived* getInstance() {
        return Manager::getInstance<Derived>();
    }
};
    
class B : public A<B>
{
public:
    std::string name = "B";
};

class C : public A<C>
{
public:
    std::string name = "C";
};

std::map<std::type_index, Base*> Manager::m_instances;

B b_inst;
C c_inst;

int main(void) {
    B *pB = B::getInstance();
    if (pB) std::cout << pB->name << std::endl;
    C *pC = C::getInstance();
    if (pC) std::cout << pC->name << std::endl;
    return 0;
}