我的问题已经很好地回答了。
但是为了以防万一人不知道,我有误解,认为一个unique_ptr<Derived>
可以移动到unique_ptr<Base>
,然后就记住了Derived
对象缺失者,即是Base
不会需要有一个虚析构函数。那是错误的。我选择Kerrek SB's comment作为“答案”,除了一个人不能这样评论。
@Howard:下面的代码说明了实现什么,我相信一个动态分配的缺失者的成本不得不意味着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;
}
干杯,
gcc链接被破坏,有人可以重新编码吗? 'gcc'有什么区别? – alfC
@alfC:没有区别。这与我的答案中显示的代码完全相同。链接是代码编译和运行的只是一个在线演示。我已经更新了它。 –
为什么不只是“std :: unique_ptr px(&x);”? –
Jon