控制反轉(Inversion of Control,縮寫爲IoC),是面向對象編程中的一種設計原則,能夠用來減低計算機代碼之間的耦合度。其中最多見的方式叫作依賴注入(Dependency Injection,簡稱DI),還有一種方式叫「依賴查找」(Dependency Lookup)編程
實現代碼:測試
#include <sstream> #include <string> #include <unordered_map> #include <memory> #include <functional> #include "anyval.h" #include "noncopyable.h" #include "singleton.h" class IocContainer : public noncopyable { public: IocContainer() {} ~IocContainer() {} template<class T, typename Depend, typename... Args> typename std::enable_if<!std::is_base_of<T, Depend>::value>::type RegisterType(const std::string& strKey) { std::function<T* (Args...)> function = [](Args... args) { return new Depend(args...); }; RegisterType(strKey, function); } template<class T, typename Depend, typename... Args> typename std::enable_if<std::is_base_of<T, Depend>::value>::type RegisterType(const std::string& strKey) { std::function<T* (Args...)> function = [](Args... args) { return new Depend(args...); }; RegisterType(strKey, function); } template<class T, typename... Args> T* Resolve(const std::string& strKey, Args... args) { auto iter = m_creatorMap.find(strKey); if (m_creatorMap.end() == iter) { return NULL; } AnyVar resolver = iter->second; std::function<T* (Args...)> function = any_cast<std::function<T* (Args...)>>(resolver); return function(args...); } template<class T, typename... Args> std::shared_ptr<T> ResolveShared(const std::string& strKey, Args... args) { T* tmp = Resolve<T, Args...>(strKey, args...); return std::shared_ptr<T>(tmp); } private: void RegisterType(const std::string& strKey, AnyVar constructor) { if (m_creatorMap.end() != m_creatorMap.find(strKey)) { throw std::invalid_argument(strKey + " : this key has already exist!"); } else { m_creatorMap.emplace(strKey, constructor); } } private: std::unordered_map<std::string, AnyVar> m_creatorMap; }; typedef Singleton<IocContainer> IocContainerAgent;
測試代碼:
this
class TestBase { public: virtual void show() = 0; }; class TestIoc : public TestBase { public: TestIoc(int a, const std::string& msg) { } void show() { std::cout << "this is TestIoc" << std::endl; } }; int main() { IocContainerAgent::get_instance().RegisterType<TestBase, TestIoc, int, std::string>("testIoc"); TestBase* pTest = IocContainerAgent::get_instance().Resolve<TestBase>("testIoc", 10, std::string("msg")); pTest->show(); return 1; }