首先,就目前而言,代码将无法正常工作。的析构函数base
至少必须是protected
(或派生类是基类的朋友)。析构函数意味着编译器private
不允许您为派生类编写析构函数。现在,假设您有一个protected
析构函数......(记住,如果您设计一个要扩展的类,请提供公共虚拟析构函数或受保护的非虚拟!)
一切都取决于 的实现SmartPointer
,特别是std::shared_ptr
(或 boost 对应物boost::shared_ptr
)能够干净地管理这种情况。该解决方案出于破坏目的执行某种类型的部分类型擦除。基本上,智能指针有一个模板化的构造函数,它接受任何可以分配给指针的base
指针,但是因为它是模板化的,所以它知道具体的类型。此时,它存储了一个合成deleter
函数,该函数将调用适当的析构函数。
为简单起见,使用std::function
:
template <typename T>
void delete_deleter( void * p ) {
delete static_cast<T*>(p);
}
template <typename T>
class shared_pointer {
T * ptr;
std::function<void(void*)> deleter;
public:
template <typename U>
shared_pointer( U* p, std::function<void()> d = delete_deleter<U> )
: ptr(p), deleter(d)
{}
~shared_pointer() {
deleter( ptr ); // call the stored destructor
}
};
该代码仅用于展示,必须针对生产进行调整(在哪里存储function
,引用计数...),但这足以让您了解:在对象的确切类型所在的唯一函数中已知(在创建智能指针时),您创建一个包装器,它将调用您需要的析构函数的确切版本(提供一些类型的擦除),然后将其留在周围,当您需要delete
对象时调用它而不是运营商delete
。
这也可以用于管理需要调用特殊方法而不是delete
:
// exhibition only!
shared_pointer<Foo> p( Factory.create(), &Factory::release );
同样,在准备好这个生产之前应该做很多工作。
用于简化擦除的依赖关系std::function
可以从问题中消除。在简单的情况下(智能指针仅支持分配new
和释放的内存),然后只需提供一个具有单个 virtual 的基类,然后使用当前实现将现有的重写从该覆盖重构为模板派生类。如果您需要进行一般情况(持有任何类型的资源),则不值得努力,只需使用or 。delete
deleter
operator()(void*)
delete_deleter
deleter
operator()(void*)
std::function
boost::function