如何在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)来实现最大的可测试性。
例如,如果有一个类
A
创建Socket
实例,我希望它依赖于Factory<ISocket>
服务。在实际代码中,我将注入Factory<Socket>
,在测试代码中,我将注入Factory<Mock<ISocket>>
,这样我就可以在不实际创建真正的socket的情况下测试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
中指定基类),但对我来说这种用法还可以,而且它有效。
接下来我需要添加的是对构造函数参数的支持。我尝试将可变模板添加到create
中:
template <typename ...TArgs>
virtual std::unique_ptr<T> create() = 0;
...但是看起来你不能在模板中使用虚方法。
- 我走的方向正确吗?
- 如果是,我应该如何在我的实现中添加支持构造函数参数?
谢谢!
create()
是一个无返回值的函数,我不知道如何让它与父类有相同的返回类型来使虚函数正常工作。 - uh oh somebody needs a pupperfactory
的create方法需要是虚函数吗? - uh oh somebody needs a pupperBaseFactory<ISocket>::create()
并获得一个Mock<ISocket>
(或Socket
)对象。 - Alon Gubkin