那么,std :: unique_ptr的定制删除器是如何工作的呢?
根据N3290, std::unique_ptr
在其构造函数中接受一个deleter参数。
但是,我不能在Windows中使用Visual C ++ 10.0或MinGW g ++ 4.4.1,也不能使用Ubuntu中的g ++ 4.6.1。
因此,我担心自己对这个问题的理解是不完整或错误的,我看不到一个明显被忽略的删除论点,那么任何人都可以提供一个工作的例子吗?
最好我也想看看unique_ptr<Base> p = unique_ptr<Derived>( new Derived )
。
可能用标准中的一些措辞来备份这个例子,也就是说,不pipe你使用的是什么编译器,它实际上是做它应该做的事情?
这在MSVC10中适用于我
int x = 5; auto del = [](int * p) { std::cout << "Deleting x, value is : " << *p; }; std::unique_ptr<int, decltype(del)> px(&x, del);
在海湾合作委员会4.5, 在这里
我会跳过去的标准,除非你不认为这个例子正在做你期望的事情。
为了补充所有以前的答案,有一种方法可以有一个自定义删除,而不必“污染”unique_ptr签名通过有一个函数指针或类似的东西等效于这样的:
std::unique_ptr< MyType, myTypeDeleter > // not pretty
这可以通过提供一个专门的std :: default_delete模板类来实现,就像这样:
namespace std { template<> class default_delete< MyType > { public: void operator()(MyType *ptr) { delete ptr; } }; }
现在所有std::unique_ptr< MyType >
这个“看到”这个专门化的东西都会被删除。 请注意,它可能不是你想要的所有std::unique_ptr< MyType >
,所以请仔细select你的解决scheme。
我的问题已经很好的回答了。
但是为了防止人们想知道,我错误地认为unique_ptr<Derived>
可以被移动到unique_ptr<Base>
,然后记住Derived
对象的删除器,也就是说Base
不需要虚拟析构函数。 那是错的。 我会selectKerrek SB的评论作为“答案”,除了一个不能做这个评论。
@Howard :下面的代码举例说明了实现我认为dynamic分配的删除程序的开销意味着unique_ptr
开箱即用的一种方式:
#include <iostream> #include <memory> // std::unique_ptr #include <functional> // function #include <utility> // move #include <string> using namespace std; class Base { public: Base() { cout << "Base:<init>" << endl; } ~Base() { cout << "Base::<destroy>" << endl; } virtual string message() const { return "Message from Base!"; } }; class Derived : public Base { public: Derived() { cout << "Derived::<init>" << endl; } ~Derived() { cout << "Derived::<destroy>" << endl; } virtual string message() const { return "Message from Derived!"; } }; class BoundDeleter { private: typedef void (*DeleteFunc)( void* p ); DeleteFunc deleteFunc_; void* pObject_; template< class Type > static void deleteFuncImpl( void* p ) { delete static_cast< Type* >( p ); } public: template< class Type > BoundDeleter( Type* pObject ) : deleteFunc_( &deleteFuncImpl< Type > ) , pObject_( pObject ) {} BoundDeleter( BoundDeleter&& other ) : deleteFunc_( move( other.deleteFunc_ ) ) , pObject_( move( other.pObject_ ) ) {} void operator() (void*) const { deleteFunc_( pObject_ ); } }; template< class Type > class SafeCleanupUniquePtr : protected unique_ptr< Type, BoundDeleter > { public: typedef unique_ptr< Type, BoundDeleter > Base; using Base::operator->; using Base::operator*; template< class ActualType > SafeCleanupUniquePtr( ActualType* p ) : Base( p, BoundDeleter( p ) ) {} template< class Other > SafeCleanupUniquePtr( SafeCleanupUniquePtr< Other >&& other ) : Base( move( other ) ) {} }; int main() { SafeCleanupUniquePtr< Base > p( new Derived ); cout << p->message() << endl; }
干杯,
这工作。 破坏正常发生。
class Base { public: Base() { std::cout << "Base::Base\n"; } virtual ~Base() { std::cout << "Base::~Base\n"; } }; class Derived : public Base { public: Derived() { std::cout << "Derived::Derived\n"; } virtual ~Derived() { std::cout << "Derived::~Derived\n"; } }; void Delete(const Base* bp) { delete bp; } int main() { std::unique_ptr<Base, void(*)(const Base*)> ptr = std::unique_ptr<Derived, void(*)(const Base*)>(new Derived(), Delete); }