C++ 公共组件-IOC库

C++ 公共组件-IOC库

参考网址:https://blog.csdn.net/alpha_love/article/details/75208889

IOC机制简介

IOC机制可以让对象之间的关系在外面组装,外界可以根据需求灵活地配置这种机制的对象创建策略,从而获得想要的目标对象,这种机制被称为控制反转(Inversion of Control,IoC)。

控制反转就是应用本身不负责依赖对象的创建和维护,而交给一个外部容器来负责。这样控制权就由应用转移到了外部IoC容器,即实现了所谓的控制反转。IoC用来降低对象之间直接依赖产生的耦合性。
具体可以参考此网址:https://blog.csdn.net/alpha_love/article/details/75208889

IOC的简单实现

github项目地址

Any.hpp(C++17之前使用)

#pragma once
#include <memory>
#include <typeindex>
#include <exception>
#include <iostream>

struct Any
{
	Any(void) : m_tpIndex(std::type_index(typeid(void))) {}
	Any(const Any& that) : m_ptr(that.Clone()), m_tpIndex(that.m_tpIndex) {}
	Any(Any && that) : m_ptr(std::move(that.m_ptr)), m_tpIndex(that.m_tpIndex) {}

	//创建智能指针时,对于一般的类型,通过std::decay来移除引用和cv符,从而获取原始类型
	template<typename U, class = typename std::enable_if<!std::is_same<typename std::decay<U>::type, Any>::value, U>::type> Any(U && value) : m_ptr(new Derived < typename std::decay<U>::type>(std::forward<U>(value))),
		m_tpIndex(std::type_index(typeid(typename std::decay<U>::type))){}

	bool IsNull() const { return !bool(m_ptr); }

	template<class U> bool Is() const
	{
		return m_tpIndex == std::type_index(typeid(U));
	}

	//将Any转换为实际的类型
	template<class U>
	U& AnyCast()
	{
		if (!Is<U>())
		{
			std::cout << "can not cast " << typeid(U).name() << " to " << m_tpIndex.name() << std::endl;
			throw std::logic_error{"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;
	}

    Any& operator=(Any&& a)
    {
        if (m_ptr == a.m_ptr)
            return *this;

        m_ptr = std::move(a.m_ptr);
        m_tpIndex = a.m_tpIndex;
        return *this;
    }

private:
	struct Base;
	typedef std::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(std::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;
	std::type_index m_tpIndex;
};

NonCopyable.hpp

#pragma once
class NonCopyable
{
public:
	NonCopyable(const NonCopyable&) = delete; // deleted
	NonCopyable& operator = (const NonCopyable&) = delete; // deleted
	NonCopyable() = default;   // available
};

Ioc_11.hpp(C++11使用)

#pragma once
#include<string>
#include<unordered_map>
#include<memory>
#include<functional>
#include "Any.hpp"
#include "NonCopyable.hpp"

using namespace std;

class IocContainer : NonCopyable
{
public:
	IocContainer() = default;
	~IocContainer() = default;

	template<class T, typename Depend, typename... Args>
    typename std::enable_if<!std::is_base_of<T,Depend>::value>::type RegisterType(const string& strKey){
		std::function<T* (Args&&...)> function = [](Args&&... args){ return new T(new Depend(std::forward<Args>(args)...)); };//通过闭包擦除了参数类型
		RegisterType(strKey, std::move(function));
	}

    template<class T, typename Depend, typename... Args>
    typename std::enable_if<std::is_base_of<T,Depend>::value>::type RegisterType(const string& strKey){
        std::function<T* (Args&&...)> function = [](Args&&... args){ return new Depend(std::forward<Args>(args)...); };
        RegisterType(strKey, std::move(function));
    }

    template <class T, typename... Args>
    void RegisterSimple(const string& strKey){
        std::function<T*(Args&&...)> function = [](Args&&... args){return new T(std::forward<Args>(args)...);};
        RegisterType(strKey,std::move(function));
    }

	template<class T, typename... Args>
	T* Resolve(const string& strKey, Args&&... args){
		if (m_creatorMap.find(strKey) == m_creatorMap.end())
			return nullptr;

		Any resolver = m_creatorMap[strKey];
		std::function<T* (Args&&...)> function = resolver.AnyCast<std::function<T* (Args&&...)>>();
		return function(std::forward<Args>(args)...);
	}

	template<class T, typename... Args>
	std::shared_ptr<T> ResolveShared(const string& strKey, Args&&... args){
		T* t = Resolve<T>(strKey, std::forward<Args>(args)...);
		return std::shared_ptr<T>(t);
	}

private:
	void RegisterType(const string& strKey, Any&& constructor){
		if (m_creatorMap.find(strKey) != m_creatorMap.end())
			throw std::invalid_argument("this key has already exist!");

		//通过Any擦除了不同类型的构造器
		m_creatorMap.emplace(strKey, constructor);
	}

private:
	unordered_map<string, Any> m_creatorMap;
};

Ioc_17.hpp(C++17使用)

#pragma once
#include<string>
#include<unordered_map>
#include<memory>
#include<functional>
#include <any>
#include "NonCopyable.hpp"

using namespace std;

class IocContainer : NonCopyable
{
public:
    IocContainer() = default;
    ~IocContainer() = default;

    template<class T, typename Depend, typename... Args>
    typename std::enable_if<!std::is_base_of<T,Depend>::value>::type RegisterType(const string& strKey){
        std::function<T* (Args&&...)> function = [](Args&&... args){ return new T(new Depend(std::forward<Args>(args)...)); };//通过闭包擦除了参数类型
        RegisterType(strKey, std::move(function));
    }

    template<class T, typename Depend, typename... Args>
    typename std::enable_if<std::is_base_of<T,Depend>::value>::type RegisterType(const string& strKey){
        std::function<T* (Args&&...)> function = [](Args&&... args){ return new Depend(std::forward<Args>(args)...); };
        RegisterType(strKey, std::move(function));
    }

    template <class T, typename... Args>
    void RegisterSimple(const string& strKey){
        std::function<T*(Args&&...)> function = [](Args&&... args){return new T(std::forward<Args>(args)...);};
        RegisterType(strKey,std::move(function));
    }

    template<class T, typename... Args>
    T* Resolve(const string& strKey, Args&&... args){
        if (m_creatorMap.find(strKey) == m_creatorMap.end())
            return nullptr;

        std::any resolver = m_creatorMap[strKey];
        std::function<T* (Args&&...)> function = std::any_cast<std::function<T* (Args&&...)>>(resolver);
        return function(std::forward<Args>(args)...);
    }

    template<class T, typename... Args>
    std::shared_ptr<T> ResolveShared(const string& strKey, Args&&... args){
        T* t = Resolve<T>(strKey, std::forward<Args>(args)...);
        return std::shared_ptr<T>(t);
    }

private:
    void RegisterType(const string& strKey, std::any&& constructor){
        if (m_creatorMap.find(strKey) != m_creatorMap.end())
            throw std::invalid_argument("this key has already exist!");

        //通过Any擦除了不同类型的构造器
        m_creatorMap.emplace(strKey, constructor);
    }

private:
    unordered_map<string, std::any> m_creatorMap;
};

main.cpp(测试用例)

#ifndef __CPP17
    #if __cplusplus > 201402L
    #       define __CPP17 (1)
    #else
    #       define __CPP17 (0)
    #endif
#endif

#ifndef __CPP14
    #if __cplusplus > 201103L
    #       define __CPP14 (1)
    #else
    #       define __CPP14 (0)
    #endif
#endif

#ifndef __CPP11
    #if __cplusplus > 199711L
    #       define __CPP11 (1)
    #else
    #       define __CPP11 (0)
    #endif
#endif

#if __CPP17
#include "Ioc_17.hpp"
#elif __CPP11
#include "Ioc_11.hpp"
#endif

#include <iostream>
using namespace std;

/*test code*/
//测试继承对象
struct Base
{
	virtual void Func(){}
	virtual ~Base(){}
};

struct DerivedB : public Base
{
	DerivedB(int a, double b):m_a(a),m_b(b)
	{
	}
	void Func()override
	{
		cout<<"DerivedB::Fun()::"<<m_a+m_b<<endl;
	}
private:
	int m_a;
	double m_b;
};

struct DerivedC : public Base
{
    void Func()override
    {
        cout<<"DerivedC::Fun()"<<endl;
    }
};

struct A
{
	A(Base * ptr) :m_ptr(ptr)
	{
	}

	void Func()
	{
		m_ptr->Func();
	}

	~A()
	{
		if(m_ptr!=nullptr)
		{
			delete m_ptr;
			m_ptr = nullptr;
		}
	}

private:
Base * m_ptr;
};

//测试普通对象
struct Bus
{
    void Func() const { std::cout <<"Bus::Func()"<<std::endl; }
};
struct Car
{
    void Func() const { std::cout <<"Car::Func()"<<std::endl; }
};


void TestIoc(){
	IocContainer ioc;
	//注册继承对象
	ioc.RegisterType<A, DerivedC>("C");      //配置依赖关系
    ioc.RegisterType<A, DerivedB, int, double>("B");   //注册时要注意DerivedB的参数int和double

    //注册普通对象
    ioc.RegisterSimple<Bus>("Bus");
    ioc.RegisterSimple<Car>("Car");

	auto c = ioc.ResolveShared<A>("C");
    c->Func();
	auto b = ioc.ResolveShared<A>("B", 1, 2.0); //还要传入参数
	b->Func();

    auto bus = ioc.ResolveShared<Bus>("Bus");
    bus->Func();
    auto car = ioc.ResolveShared<Car>("Car");
    car->Func();

}

int main() {
    TestIoc();

    return 0;
}
发布了155 篇原创文章 · 获赞 15 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/wangdamingll/article/details/105067279
今日推荐