我正在努力在C ++ 11中创建一个工厂库(类似于https://github.com/google/guice,可用于Java),以熟悉模板编程,以及创建一个有用的依赖性减少工具。这个想法是工厂将抽象出对象的创建和销毁的细节,并隐藏实现细节。理想情况下,我想要有类似的东西:
InterfaceClass
{
public:
virtual void doSomething () = 0;
virtual ~InterfaceClass () {};
}
// Might need custom deleter depending on how the class was allocated
// (might come from a pool, etc)
ImplementationClass : public InterfaceClass
{
public:
// Some (possibly) complicated constructor.
ImplementationClass(Dependency one, Other dependency) {}
virtual void doSomething ()
{
// Implementation
}
virtual ~ImplementationClass ()
{
}
}
理想情况下,我希望图书馆的最终用户能够(或类似的东西):
std::unique_ptr<InterfaceClass> object = factory<InterfaceClass>();
如果所有类都使用默认删除器,则此方法很有用,但对于自定义删除器,unique_ptr的类型更改为:
std::unique_ptr<I>
为:
std::unique_ptr<I, deleter>
- 据我所知,这些类型不兼容。
有没有办法可以定义某种更高级别的“唯一指针”,它不关心它的类型签名中的删除器?其他可能的解决方法是使API与对象的创建/删除无关?
谢谢!
答案 0 :(得分:3)
使用std::function
拥有通用类型删除的删除器。
#include <iostream>
#include <memory>
#include <functional>
template<typename T>
using TypeErasedUPtr = std::unique_ptr<T, std::function<void(T*)>>;
int main()
{
TypeErasedUPtr<int> p1{new int(5), [](int* x){ delete x; }};
TypeErasedUPtr<int> p2{someAllocator<int>(5), [](int* x){ someDeallocator(x); }};
// `p1` and `p2` have the same type, `TypeErasedUPtr<int>`.
return 0;
}
这是有效的,因为std::unique_ptr<T, TDeleter>
采用可以使用TDeleter
参数调用的任何可调用T*
类型。
std::function<void(T*)>
满足了这些要求,并且还在运行时以任意形式包含任何类型的函数(通过支付较小的运行时开销价格)。
答案 1 :(得分:0)
您始终可以包装需要自定义删除器的类型。实际上你应该这样做,因为自定义删除器是你不希望暴露给公众的实现细节。