c – 带有API的`std :: shared_ptr`的智能指针模拟,用于将回调绑定到refcount修改事件,例如释放/保留……这是一件事吗?

我需要一个智能指针结构 – 类似于std :: shared_ptr – 它为我提供了一些带有暴露挂钩的API,对其进行refcount修改事件的回调(例如release / retain,aka refcout increment / decrement)可以绑定.

我想要自己实现,或者使用现成的东西,如果存在的话.

就像,我想最好能够说“每当你增加引用计数时调用这个可调用项[但是在减少时就调用那个]”同时定义这个假定的shared_ptr-ish智能指针(就像分别使用delete-expressions和deleter functor一样) ,在shared_ptr和unique_ptr定义中).

编辑(从我下面的评论) – 这就是为什么我想要这个:我目前有一个Image类模板,它的核心是std :: shared_ptr,它持有一个(可能很大的)连续堆分配的内存块. Image具有实现hyperslab迭代器(暴露例如颜色平面,CBIR散列数据和& c)的内部类,其使用std :: weak_ptr来引用回拥有的Image实例的存储器块.我想为特定的refcounted运行时扩展Image – 例如Python c-api – 并且绑定到现有的std :: shared_ptr refcounter设备比保持两个不同的系统同步更可取.

最佳答案 shared_ptr的默认实现具有共享一个对象的shared_ptr,所有对象都指向所谓的控制块.正是这个控制块保存了参考计数器,因此是更自然地可以对参考计数变化作出反应的对象.

但是,如果您真的想通过智能指针进行操作,则可能会有以下情况:

using std::shared_ptr;

template<class T> class sharedX_ptr;

// the type of function to call when a refcount change happens
template<class T>
void inc_callback(const sharedX_ptr<T>& p)
{
  std::cout << "Increasing refcount via " << &p
            << ", for object: " << p.get() << ", use_count: " << p.use_count()
            << std::endl;
}

template<class T>
void dec_callback(const sharedX_ptr<T>& p)
{
  std::cout << "About to decrease refcount via " << &p
            << ", for object: " << p.get() << ", use_count: " << p.use_count()
            << std::endl;
}

template<class T>
class sharedX_ptr : public shared_ptr<T>
{
  typedef void (*callback)(const sharedX_ptr<T>&);
  callback inc, dec;
public:
  typedef shared_ptr<T> base;

  sharedX_ptr(const sharedX_ptr& p) : base(p), inc(p.inc), dec(p.dec)
  { if (this->get()) inc(*this); }

  template<class U>
  sharedX_ptr(sharedX_ptr<U>&& p) : base(std::move(p)), inc(p.inc), dec(p.dec)
  { /*if (this->get()) inc(*this);*/ }

  template<class U>
  sharedX_ptr(shared_ptr<U> p, callback i = inc_callback<T>, callback d = dec_callback<T>)
    : shared_ptr<T>(std::move(p)), inc(i), dec(d)
    { if (this->get()) inc(*this); }

  sharedX_ptr& operator=(sharedX_ptr&& p) {
    if (this != &p) {
      if (this->get()) dec(*this);
      base::operator=(std::move(p)); inc = p.inc; dec = p.dec;
      /* if (this->get()) inc(*this); */
    }
    return *this;
  }

  template<class U>
  sharedX_ptr& operator=(const sharedX_ptr& p) {
    if (this != &p) {
      if (this->get()) dec(*this);
      base::operator=(p); inc = p.inc; dec = p.dec;
      if (this->get()) inc(*this);
    }
    return *this;
  }

  void reset() { if (this->get()) dec(*this); shared_ptr<T>::reset();}

  ~sharedX_ptr() { if (this->get()) dec(*this); }
};
点赞