componentes de la biblioteca pública de C ++ -IOC

componentes de la biblioteca pública de C ++ -IOC

Referencia URL: https: //blog.csdn.net/alpha_love/article/details/75208889

COI mecanismos Introducción

mecanismo COI puede hacer que la relación entre los objetos fuera del conjunto, el mundo exterior se puede configurar de forma flexible de acuerdo con el objeto de tales necesita un mecanismo para crear una estrategia para obtener público objetivo quiere, este mecanismo se conoce como la inversión de control (Inversión de Control, COI).

Inversión de Control es la aplicación en sí no es responsable de la creación y el mantenimiento de objetos dependientes, y a un recipiente externo a ser responsables. Tales cambios de control al exterior por el contenedor IoC aplicación, es decir, para lograr una denominada inversión de control. COI para reducir el acoplamiento entre objetos generados es directamente dependiente.
En concreto se refieren a esta URL: https: //blog.csdn.net/alpha_love/article/details/75208889

implementación sencilla de la COI

Dirección del proyecto github

Any.hpp (C ++ 17 antes de su uso)

#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 uso)

#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 utilizado)

#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 (caso de prueba)

#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;
}
Publicados 155 artículos originales · ganado elogios 15 · vistas 160 000 +

Supongo que te gusta

Origin blog.csdn.net/wangdamingll/article/details/105067279
Recomendado
Clasificación