在C++中键入擦除:boost :: shared_ptr和boost :: function如何工作?

pic*_*c11 18 c++ boost type-erasure

类型擦除 - 你怎么称呼它?

如何boost::shared_ptr存储其删除器以及如何boost::function存储其功能对象?

有没有教授这个技巧的教程?

使用类型擦除函数对象的运行时成本是多少?

Dav*_*eas 23

这个想法很简单,您可以定义一个基类,该基类具有您需要的功能的接口,然后继承它.由于类型擦除类仅使用该接口,因此忘记删除下面的实际类型.或者,如果唯一需要的接口可以表示为自由函数,则可以存储指向自由函数的指针.

namespace detail {
   struct deleter_base {
      virtual ~deleter_base() {}
      virtual void operator()( void* ) = 0;
   };
   template <typename T>
   struct deleter : deleter_base {
      virtual void operator()( void* p ) {
         delete static_cast<T*>(p);
      }
   };
}
template <typename T>
class simple_ptr {
   T* ptr;
   detail::deleter_base* deleter;
public:
   template <typename U>
   simple_ptr( U* p ) {
      ptr = p;
      deleter = new detail::deleter<U>();
   }
   ~simple_ptr() {
      (*deleter)( ptr );
      delete deleter;
   }
};
Run Code Online (Sandbox Code Playgroud)

这是一个非常简化的智能指针,但这个想法就在那里.在特定情况下shared_ptr,删除器被存储为引用计数对象的一部分,该对象由指针保持.

  • @ pic11:传递给`shared_ptr`的删除器不需要继承,*但*类型擦除是通过内部使用继承(或函数指针)实现的. (6认同)
  • @ Mr.Anubis:举个例子可能更容易:`void f(shared_ptr <int>)`和两个共享指针:`shared_ptr <int> p(new int); int i; shared_ptr <int> q(&i,noop_deleter);`(假设适当的删除者).删除者不参与`shared_ptr`的类型,这意味着你可以同时执行`f(p)`和`f(q)`.将它与`std :: unique_ptr`比较,其中deleter是一个模板参数:`void f(unique_ptr <int>)`,`unique_ptr <int,noop> q(&i)`,然后`f(q)`是一个错误.删除器的类型是智能指针类型的一部分. (2认同)