我可以抽象出有关模板化类的具体细节吗?

时间:2015-04-04 18:45:46

标签: c++ templates c++11 factory unique-ptr

我正在努力在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与对象的创建/删除无关?

谢谢!

2 个答案:

答案 0 :(得分:3)

使用std::function拥有通用类型删除的删除器。

Ideone link

#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)

您始终可以包装需要自定义删除器的类型。实际上你应该这样做,因为自定义删除器是你不希望暴露给公众的实现细节。