c – 如何实现支持模板协方差的通用工厂?

前端之家收集整理的这篇文章主要介绍了c – 如何实现支持模板协方差的通用工厂?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如何在C 14中实现支持模板协方差的通用工厂?

我希望实现这样的目标:

std::shared_ptr<Factory<BaseClass>> factory = 
    std::make_shared<Factory<DerivedClass>>();

auto x = factory->create(arg1,arg2,arg3);

请注意,在factory-> create中,您可以将任何参数传递给DerivedClass构造函数.可以假设BaseClass构造函数和DerivedClass是相同的.

为了避免XY问题,我需要这个的原因是因为我想使用依赖注入(boost::di)来实现最大可测试性.

例如,如果有一个创建Socket实例的类A,我希望它依赖于Factory< ISocket>服务.在实际代码中,我注入了Factory< Socket>,在测试代码中,我注入了Factory< Mock< ISocket>>,所以我可以测试A类而不实际创建一个真正的套接字.

这是我目前的尝试:

template <typename T>
struct BaseFactory {
    virtual std::unique_ptr<T> create() = 0;
};

template <typename TInterface,typename TImplementation>
struct Factory : public BaseFactory<TInterface> {
    virtual std::unique_ptr<TInterface> create() override {
        return std::make_unique<TImplementation>();  
    }
};

目前的用法是这样的:

std::shared_ptr<BaseFactory<ISocket>> factory = 
    std::make_shared<Factory<ISocket,Socket>>();

auto x = factory->create();

虽然不理想(你需要在Factory中指定基类),但这种用法对我来说很好,而且有效.

我需要添加的下一件事是对构造函数参数的支持.我试图添加variadic模板来创建:

template <typename ...TArgs>
virtual std::unique_ptr<T> create() = 0;

…但看起来你不能拥有带模板的虚拟方法.

>我正朝着正确的方向前进吗?
>如果是,我应该如何在我的实现中添加对构造函数参数的支持

谢谢!

解决方法

好的,我找到了一个解决方案,但它并不漂亮:
template <typename T,typename ...TArgs>
struct BaseFactory {
    virtual std::unique_ptr<T> create(TArgs&&... args) = 0;
};

template <typename TInterface,typename TImplementation,typename ...TArgs>
struct Factory : public BaseFactory<TInterface,TArgs...> {
    virtual std::unique_ptr<TInterface> create(TArgs&&... args) override {
        return std::make_unique<TImplementation>(std::forward<TArgs>(args)...);
    }
};

using ISocketFactory = BaseFactory<ISocket,int>;
using SocketFactory = Factory<ISocket,Socket,int>;

int main() {
    std::shared_ptr<ISocketFactory> socket_factory = 
        std::make_shared<SocketFactory>();

    std::unique_ptr<ISocket> socket = socket_factory->create(1234);
    socket->read();
    socket->write();
}

我们的想法是在BaseFactory和Factory模板中传递实现类的构造函数参数.在这种情况下,Socket构造函数应该类似于:

Socket(int n);

你知道如何优化这个吗? (更少的样板代码)

猜你在找的C&C++相关文章