我的問題已經很好地回答了。
但是爲了以防萬一人不知道,我有誤解,認爲一個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