C ++のパブリックライブラリコンポーネント-IOC

C ++のパブリックライブラリコンポーネント-IOC

参考URL:httpsを://blog.csdn.net/alpha_love/article/details/75208889

IOCのメカニズムはじめに

IOC機構は、アセンブリ外のオブジェクト間の関係を作ることができ、外の世界を柔軟ターゲットオーディエンスの欲求を得るための戦略を作成するために、そのような機構の必要の目的に応じて設定することができ、このメカニズムは、制御の反転制御(反転として知られていますIOC)。

制御の逆転は、アプリケーション自体が従属オブジェクトを作成し、維持する責任を負わないものであり、外部容器に関与すると。コントロールのいわゆる反転を達成するために、アプリケーションIoCコンテナ、即ちて外部にこのような制御に移行します。生成されたオブジェクトとの間の結合を低減するためのIOCは直接依存します。
具体的に次のURLを参照してくださいます。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 ビュー160 000 +

おすすめ

転載: blog.csdn.net/wangdamingll/article/details/105067279