`std::shared_ptr` 的智能指针模拟与 API 绑定回调到引用计数修改事件,例如release/retain ……这是一回事吗?
Smart pointer analog of `std::shared_ptr` with API to bind callbacks to refcount-modifying events e.g. release/retain … is this a thing?
我需要一个智能指针结构 - 类似于 std::shared_ptr
- 它为我提供了某种 API 和暴露的钩子,回调到引用计数修改事件(例如release/retain,又名 refcout increment/decrement) 可以绑定。
我要么想自己实现,要么使用现成的东西,如果它存在的话。
就像,我希望在定义这个推定的 shared_ptr
-ish 智能指针(就像 delete -expressions 和 deleter functor 分别在 shared_ptr
和 unique_ptr
定义中使用。
编辑(来自我下面的评论)——这就是我想要这个的原因:我目前有一个图像 class 模板,其核心是一个 std::shared_ptr 持有(可能很大)连续堆分配的内存块。 Image 具有内部 classes 实现 hyperslab 迭代器(公开例如颜色平面、CBIR 哈希数据等),这些迭代器使用 std::weak_ptr 来引用所属 Image 实例的内存块。我想为特定的 refcounted 运行时扩展图像——例如 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); }
};
我需要一个智能指针结构 - 类似于 std::shared_ptr
- 它为我提供了某种 API 和暴露的钩子,回调到引用计数修改事件(例如release/retain,又名 refcout increment/decrement) 可以绑定。
我要么想自己实现,要么使用现成的东西,如果它存在的话。
就像,我希望在定义这个推定的 shared_ptr
-ish 智能指针(就像 delete -expressions 和 deleter functor 分别在 shared_ptr
和 unique_ptr
定义中使用。
编辑(来自我下面的评论)——这就是我想要这个的原因:我目前有一个图像 class 模板,其核心是一个 std::shared_ptr 持有(可能很大)连续堆分配的内存块。 Image 具有内部 classes 实现 hyperslab 迭代器(公开例如颜色平面、CBIR 哈希数据等),这些迭代器使用 std::weak_ptr 来引用所属 Image 实例的内存块。我想为特定的 refcounted 运行时扩展图像——例如 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); }
};