引用计数(不存储任何数据)

Reference counting (without storing any data)

本文关键字:任何 数据 存储 引用      更新时间:2023-10-16

我需要在我的类中有一个共享计数器(当计数器变为零时调用某个函数)。为此,我可以使用带有删除器的shared_ptr<char>,但这种方法的开销是分配不需要的char并保留指向它的指针。

基本上,我需要shared_ptr的引用计数部分。我不知道如何利用shared_ptr并避免这种开销。

是否有共享计数器的可移植C++11实现(即仅使用标准c ++ 11和std,没有显式互斥体等)?

附言。计数器并非整个类所独有。我的类可能有对象 a1、a2、a3 共享同一个计数器。和共享不同计数器的 b1、b2、b3。因此,当 a1、a2、a3 中的最后一个超出范围时,应该会发生一些事情(与 a1、a2、a3 相关)。当 b1、b2、b3 的最后一个超出范围时,应该会发生一些事情(与 b1、b2、b3 相关)。

谢谢

一个简单的

atomic<int>就足够了。我认为不需要更复杂的东西。

std::shared_ptr<void> p(nullptr, MyDeleter());

这完全符合您的要求。

现场示例

尝试std::shared_ptr<void> ptr = std::make_shared<char>(); . 这确实具有单个字节开销(可能出于对齐原因而四舍五入),但是当您使用 make_shared 创建shared_ptr时,分配的char与引用计数实现位于同一块中。

另一种方法是使用"在退出范围"对象:

struct at_exit_scope {
  std::function<void()> f;
  ~at_exit_scope() { f(); }
  template<typename F>
  at_exit_scope( F&& f_ ):f(std::forward<F>(f_)) {}
  at_exit_scope() = delete;
  at_exit_scope(at_exit_scope const&) = delete;
};

然后做一个shared_ptr<at_exit_scope> ptr = std::make_shared<at_exit_scope>( [=]{ /* code */ } ). 这消除了对deleter的需要,并用std::function的开销代替了它。