[11 使用C++11开发一个轻量级的IoC容器(工厂模式的应用及优化)] 11.2 IoC创建对象

一个可配置的对象工厂实现思路如下:
1 先注册可能需要创建对象的构造函数,将其放到一个内部关联容器map中,设置键为类型的名字,值为类型的构造函数。
2 然后在创建的时候根据类型名称查找对应的构造函数并最终创建出目标对象。

可配置的对象工厂如下:

#include <string>
#include <map>
#include <memory>
#include <functional>
using namespace std;

template<class T>
class IocContainer
{
public:
    IocContainer() {}
    ~IocContainer() {}

    // 注册需要创建对象的构造函数
    template<class Drived>
    void RegisterType(string strKey)
    {
        std::function<T*()> function = []{return new Drived();};
        RegisterType(strKey, function);
    }

    // 根据唯一标识查找对应的构造函数,并创建指针对象
    T* Resolve(string strKey)
    {
        if (m_creatorMap.find(strKey) == m_creatorMap.end())
        {
            return nullptr;
        }
        std::function<T*()> function = m_creatorMap(strKey);
        return function();
    }

    // 创建智能指针对象
    std::shared_ptr<T> ResolveShared(string strKey)
    {
        T* ptr = Resolve(strKey);
        return std::shared_ptr<T>(ptr);
    }
    
private:
    void RegisterType(string strKey, std::function<T*()> creator)
    {
        if (m_creatorMap.find(strKey) != m_creatorMap.end()) {
            throw std::invalid_argument("this key has already exist!");
        }
        m_creatorMap.emplace(strKey, creator);
    }

private:
    map<string, std::function<T*()>> m_creatorMap;
};

测试代码如下:

struct ICar
{
    virtual ~ICar() {}
    virtual void test() const = 0;
};
struct Bus : ICar
{
    Bus() {};
    void test() const { cout << "Bus::test()" << endl; };
};
struct Car : ICar
{
    Car() {};
    void test() const { cout << "Car::test()" << endl; };
};

int main()
{
    IocContainer<ICar> carioc;
    // Bus,ICar继承关系
    carioc.RegisterType<Bus>("bus");
    carioc.RegisterType<Car>("car");
    
    std::shared_ptr<ICar> bus = carioc.ResolveShared("bus");
    bus->test();
    std::shared_ptr<ICar> car = carioc.ResolveShared("car");
    car->test();

    return 0;
}

输出结果:

Bus::test()
Car::test()

上述代码可以创建所有的无参数的ICar派生对象。但还有如下两点不足:

(1)只能创建无参对象,不能创建有参数的对象。

(2)只能创建一种接口类型ICar的对象,通过ioccar实例不能创建所有类型的对象。

如果希望能够创建所有类型的对象,则需要通过类型擦除来实现。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值