2017-01-01 299 views
1

我想使用unique_ptr与我的删除程序。 我想我的我的unique_ptr与我的删除器完全兼容与unique_ptr与默认deleter。std :: unique_ptr,自定义删除和类型更改

我这样做:

template <typename T> 
struct QObjectDeleteLaterDeletor : 
     public std::default_delete<T> 
{ 
    void operator()(T *p) 
    { 
     p->deleteLater(); 
    } 
}; 

template <typename T, class... Args> 
std::unique_ptr<T> qtMakeUniqueSpecial(Args&&... args) 
{ 
    return std::unique_ptr<T>(
       new T(std::forward<Args>(args)...), 
       QObjectDeleteLaterDeletor<T>()); 
} 

这编译,但不起作用。我的自定义删除程序被忽略,并使用默认的删除程序,就好像我根本没有指定它一样。

我需要所有的这是可以做到这样的事情:

auto ptr1 = qtMakeUniqueSpecial<MyObject>(); 
std::unique_ptr<MyObject> ptr2; 
ptr2 = std::move(ptr1); 

请注意,现在连ptr1.reset()将导致调用标准缺失者,不是我一个。

这有可能吗?

+1

但是在移动之后,'ptr1'没有指向数据的指针。在移动到“删除”后调用'ptr1'上的'reset'是没有意义的。您可以创建一个[最小,完整和可验证示例](http://stackoverflow.com/help/mcve)并向我们展示?并且请告诉我们*你怎么知道你的删除器没有被调用,但是默认是。 –

+2

不,你正在做的就是将你喜欢的删除器切回到'default_delete'。 –

+0

当然,我在移动之前称重置。最小的例子是在这个问题。 –

回答

1

您正在尝试使用

namespace std { 
    template<typename T, typename Deleter = default_delete<T> > 
    class unique_ptr; 
} 

具有第二模板参数Deleter。未能指定,默认为std::default_delete<T>。您的代码

std::unique_ptr<T>(new T(std::forward<Args>(args)...), 
        QObjectDeleteLaterDeletor<T>()); 

传递一个const std::default_delete<T>&constructor of std::unique_ptr<T>,因为这是构造函数需要什么。销毁后(或致电成员reset()),将会被调用。

请注意,std::shared_ptr的行为是不同的:删除程序没有第二个模板参数,但可以在构造时提供自定义删除程序(这需要通过类型擦除进行存储,这可以通过std::unique_ptr来避免)。

2

您需要指定QObjectDeleteLaterDeletor作为模板参数;否则,将使用std::default_delete作为从QObjectDeleteLaterDeletor进行分片复制的删除器。

template <typename T, class... Args> 
std::unique_ptr<T, QObjectDeleteLaterDeletor<T>> qtMakeUniqueSpecial(Args&&... args) 
{ 
    return std::unique_ptr<T, QObjectDeleteLaterDeletor<T>> (
       new T(std::forward<Args>(args)...), 
       QObjectDeleteLaterDeletor<T>()); 
} 

请注意,您声明ptr2std::unique_ptr<MyObject>,然后ptr2std::default_delete破坏指针。如果你声明其类型符合ptr1,如auto ptr2 = std::move(ptr1);那么它会没事的。

+0

不,这不适合我。请阅读我的问题。 –

+0

我想我的类型是std :: unique_ptr 。不unique_ptr 。 –

+0

它可能与shared_ptr和似乎是不可能的unique_ptr。 –