#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;
}