我可以抽象出有关模板 类 的具体细节吗?
Can I abstract away specific details about templated classes?
我正在使用 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>
-- 据我所知,这些类型不兼容。
有没有一种方法可以定义某种更高级别的 "unique pointer",它不关心类型签名中的删除器?保持 API 对对象的创建/删除不可知的其他可能的解决方法?
谢谢!
使用 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>
接受任何可以用 T*
参数调用的可调用 TDeleter
类型。
一个 std::function<void(T*)>
满足了这个要求,并且还在 运行 时间以多态方式包装了具有该签名的任何类型的函数(通过支付小的 运行 时间开销价格)。
您始终可以包装需要自定义删除器的类型。实际上你 应该 这样做,因为自定义删除器是你不希望暴露给 public 的实现细节。
我正在使用 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>
-- 据我所知,这些类型不兼容。
有没有一种方法可以定义某种更高级别的 "unique pointer",它不关心类型签名中的删除器?保持 API 对对象的创建/删除不可知的其他可能的解决方法?
谢谢!
使用 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>
接受任何可以用 T*
参数调用的可调用 TDeleter
类型。
一个 std::function<void(T*)>
满足了这个要求,并且还在 运行 时间以多态方式包装了具有该签名的任何类型的函数(通过支付小的 运行 时间开销价格)。
您始终可以包装需要自定义删除器的类型。实际上你 应该 这样做,因为自定义删除器是你不希望暴露给 public 的实现细节。