Does shared_ptr's dtor require the use of a “deleter”?

£可爱£侵袭症+ 提交于 2019-12-03 04:10:44

Question: Where is this required?

If it wasn't required the destructor would have undefined behaviour, and the standard is not in the habit of requiring undefined behaviour :-)

If you meet the preconditions of the constructor, then the destructor will not invoke undefined behaviour. How the implementation ensures that is unspecified, but you can assume it gets it right, and you don't need to know how. If the implementation wasn't expected to Do The Right Thing then the destructor would have a precondition.

(Or am I just too nit-picky and it's obvious somehow that the implementations are required to use a "owner object"?)

Yes, there has to be some additional object created to own the pointer, because the reference counts (or other bookkeeping data) must be on the heap and not part of any specific shared_ptr instance, because it might need to out-live any specific instance. So yes, there is an extra object, which owns the pointer, which you can call an owner object. If no deleter is supplied by the user then that owner object just calls delete. For example:

template<typename T>
struct SpOwner {
  long count;
  long weak_count;
  T* ptr;
  virtual void dispose() { delete ptr; }
  // ...
};

template<typename T, typename Del>
struct SpOwnerWithDeleter : SpOwner<T> {
  Del del;
  virtual void dispose() { del(this->ptr); }
  // ...
};

Now a shared_ptr has a SpOwner* and when the count drops to zero it invokes the virtual function dispose() which either calls delete or invokes the deleter, depending on how the object was constructed. The decision of whether to construct an SpOwner or an SpOwnerWithDeleter is made when the shared_ptr is constructed, and that type is still the same when the shared_ptr is destroyed, so if it needs to dispose of the owned pointer then it will Do The Right Thing.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!