Skip to content

Instantly share code, notes, and snippets.

@skyrpex
Last active October 13, 2015 14:30
Show Gist options
  • Save skyrpex/2c45b9d8cc4c2c15a375 to your computer and use it in GitHub Desktop.
Save skyrpex/2c45b9d8cc4c2c15a375 to your computer and use it in GitHub Desktop.
Inversion Of Control in C++
#include <iostream>
#include <typeinfo>
#include <typeindex>
#include <functional>
#include <memory>
#include <unordered_map>
class AbstractTest
{
public:
virtual void yeah()
{
std::cout << "I'm AbstractTest! " << typeid(AbstractTest).name() << std::endl;
}
};
class Test : public AbstractTest
{
public:
void yeah() override
{
log();
}
void log()
{
std::cout << "I'm Test! " << typeid(Test).name() << std::endl;
}
};
class Test2 : public AbstractTest
{
public:
void log()
{
std::cout << "I'm Test2! " << typeid(Test).name() << std::endl;
}
};
namespace ioc
{
class Container
{
public:
class AbstractInstance
{
public:
virtual ~AbstractInstance() {}
};
template<typename T>
class Instance : public AbstractInstance
{
public:
Instance(T *ptr) : ptr(ptr) {}
std::shared_ptr<T> ptr;
};
template<typename T>
void registerType(std::function<T * ()> callback)
{
m_callbacks[std::type_index(typeid(T))] = callback;
}
template<typename T>
std::shared_ptr<T> make()
{
auto type = std::type_index(typeid(T));
auto search = m_instances.find(type);
if (search != m_instances.end()) {
auto instance = std::static_pointer_cast<Instance<T>>(search->second);
return instance->ptr;
}
void *ptr = m_callbacks[type]();
auto instance = std::make_shared<Instance<T>>(static_cast<T *>(ptr));
m_instances[type] = instance;
return instance->ptr;
}
protected:
std::unordered_map<std::type_index, std::function<void * ()>> m_callbacks;
std::unordered_map<std::type_index, std::shared_ptr<AbstractInstance>> m_instances;
};
}
int main()
{
ioc::Container container;
container.registerType<AbstractTest>([]() {
return new Test();
});
// container.registerType<Test2>([]() {
// return new Test2();
// });
auto test = container.make<AbstractTest>();
// test->log();
test->yeah();
// auto test2 = container.make<Test>();
// std::cout << (test == test2) << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment