Any.h:Any类型
#pragma once
#include <memory>
#include <typeindex>
/*
类似于boost Any类的实现
*/
struct Any {
public:
Any(void) :m_tpIndex(type_index(typeid(void))) {}
Any(Any& that) :m_ptr(that.Clone()), m_tpIndex(that.m_tpIndex) {}
Any(Any&& that) :m_ptr(move(that.m_ptr)), m_tpIndex(that.m_tpIndex) {}
// 创建智能指针时,对于一般的类型,通过decay来移除引用和CV符,从而获取原始类型
template<typename U, class = typename enable_if<!is_same<typename decay<U>::type, Any>::value, U>::type>
Any(U &&value) : m_ptr(new Derived<typename decay<U>::type>(forward<U>(value))), m_tpIndex(type_index(typeid(typename decay<U>::type))) {}
bool IsNull() const { return !bool(m_ptr); }
template<class U>bool Is() const {
return m_tpIndex == type_index(typeid(U));
}
// 将Any转换成实际的类型
template<class U>
U& AnyCast()
{
if (!Is<U>())
{
cout << "can not cast " << typeid(U).name() << " to " << m_tpIndex.name() << endl;
throw bad_cast();
}
auto derived = dynamic_cast<Derived<U>*> (m_ptr.get());
return derived->m_value;
}
Any operator=(const Any& a)
{
if (m_ptr == a.m_ptr)
return *this;
m_ptr = a.Clone();
m_tpIndex = a.m_tpIndex;
return *this;
}
private:
struct Base;
typedef unique_ptr<Base> BasePtr;
struct Base
{
virtual ~Base() {}
virtual BasePtr Clone() const = 0;
};
template<typename T>
struct Derived :Base
{
template<typename U>
Derived(U&& value) :m_value(forward<U>(value)) {}
BasePtr Clone() const {
return BasePtr(new Derived<T>(m_value));
}
T m_value;
};
BasePtr Clone() const
{
if (m_ptr != nullptr)
{
return m_ptr->Clone();
}
return nullptr;
}
BasePtr m_ptr;
type_index m_tpIndex;
};
NonCopyable.h:不可复制类
#pragma once
class NonCopyable
{
protected:
NonCopyable() = default;
~NonCopyable() = default;
// 禁用复制构造
NonCopyable(const NonCopyable&) = delete;
// 禁用赋值构造
NonCopyable& operator = (const NonCopyable&) = delete;
};
IOC.h:IOC实现
#pragma once
#include <string>
#include <unordered_map>
#include <memory>
#include <functional>
using namespace std;
#include "Any.h"
#include "NonCopyable.h"
class IocContainer :NonCopyable
{
public:
IocContainer(void) {}
~IocContainer(void) {}
template<class T, typename Depend, typename... Args>
typename enable_if<!is_base_of<T,Depend>::value>::type RegisterType(const string& strKey)
{
function<T* (Args...)> func = [](Args... args) {return new T( new Depend(args...)); };//通过闭包擦除了参数类型
RegisterType(strKey, func);
}
template<class T, typename Depend, typename... Args>
typename enable_if<is_base_of<T,Depend>::value>::type RegisterType(const string& strKey)
{
function<T* (Args...)> function = [](Args...args) {return new Depend(args...); }; //通过闭包擦除了参数类型
RegisterType(strKey, function);
}
template<class T,typename...Args>
void RegisterSimple(const string& strKey)
{
function<T* (Args...)> function = [](Args... args) {return new T(args...); };
RegisterType(strKey, function);
}
template<class T,typename... Args>
T* Resolve(const string& strKey, Args...args)
{
auto it = m_creatorMap.find(strKey);
if (it == m_creatorMap.end())
return nullptr;
Any resolver = it->second;
function<T* (Args...)> func = resolver.AnyCast<function<T* (Args...)>>();
return func(args...);
}
template<class T,typename... Args>
shared_ptr<T> ResolveShared(const string& strKey, Args...args)
{
T* t = Resolve<T>(strKey, args...);
return shared_ptr<T>(t);
}
private:
void RegisterType(const string& strKey,Any constructor)
{
if (m_creatorMap.find(strKey) != m_creatorMap.end())
{
throw ::invalid_argument("this key has already exist!");
}
// 通过Any擦除了不同类型的构造器
m_creatorMap.emplace(strKey, constructor);
}
private:
unordered_map<string, Any> m_creatorMap;
};
测试代码:
// IOC.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include "IOC.h"
using namespace std;
struct IX
{
virtual void g() {}
virtual~IX() {}
};
class X :public IX
{
public:
void g()
{
cout << "it is a test in x" << endl;
}
};
class Y :public IX
{
public:
void g()
{
cout << "it is a test in y " << endl;
}
};
struct MyStructA
{
MyStructA(IX* x) :m_x(x) {}
~MyStructA()
{
if (m_x != nullptr)
{
delete m_x;
m_x = nullptr;
}
}
void Fun() { m_x->g(); }
private:
IX* m_x;
};
int main()
{
{
MyStructA *pa = new MyStructA(new X()); //直接创建依赖对象
pa->Fun();
delete pa;
}
IocContainer ioc;
ioc.RegisterType<MyStructA, X>("A"); //配置依赖关系
// 通过Ioc容器去创建目标对象及其依赖的对象
shared_ptr<MyStructA> pb = ioc.ResolveShared<MyStructA>("A");
pb->Fun();
ioc.RegisterType<MyStructA, Y>("A1");
auto pc = ioc.ResolveShared<MyStructA>("A1");
pc->Fun();
}
测试结果: