What is the rationale for the difference in destruction behavior between std::unique_ptr and std::shared_ptr?
来自http://en.cppreference.com/w/cpp/memory/unique_ptr:
If
T is derived class (sic) of some baseB , thenstd::unique_ptr is
implicitly convertible tostd::unique_ptr . The default deleter of
the resultingstd::unique_ptr will use operator delete forB ,
leading to undefined behavior unless the destructor ofB is virtual.
Note thatstd::shared_ptr behaves differently:std::shared_ptr will
use the operator delete for the typeT and the owned object will be
deleted correctly even if the destructor ofB is not virtual.
号
以上描述的破坏行为差异的基本原理是什么?我最初的猜测是表演?
同样有趣的是,如果
一个
cleanup函数是
当更改托管类型(
因为
对于
为了支持从基到基的强制转换和从派生到删除,必须存储额外的状态,记住
但是,这将使EDOCX1的大小增加一倍(11),或者要求它将数据存储在堆的某个地方。
决定
现在,您可以通过简单地添加一个删除程序类型并存储一个知道它正在破坏的对象类型的破坏函数来教会
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | struct deleter { void* state; void(*f)(void*); void operator()(void*)const{if (f) f(state);} deleter(deleter const&)=default; deleter(deleter&&o):deleter(o) { o.state = nullptr; o.f=nullptr; } deleter()=delete; template<class T> deleter(T*t): state(t), f([](void*p){delete static_cast<T*>(p);}) {} }; template<class T> using smart_unique_ptr = std::unique_ptr<T, deleter>; template<class T, class...Args> smart_unique_ptr<T> make_smart_unique( Args&&... args ) { T* t = new T(std::forward<Args>(args)...); return { t, t }; } |
实况例子中,我生成一个唯一的ptr到派生,将它存储在一个唯一的ptr到base中,然后重置base。派生指针将被删除。
(一个简单的
请注意,在不更改删除程序的情况下更改存储在此类