C++11 Ioc--Inversion of Control控制反转

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();

}


测试结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小蚂蚁_CrkRes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值