如何通过unsigned long传递std :: shared_ptr回调?

Rag*_*nar 4 c++ shared-ptr

我有一个旧的C风格的库,它使用无符号long的回调用于用户参数,我想将我的shared_ptr传递给回调,以便引用计数递增.

void callback( unsigned long arg ) {
  std::shared_ptr<my_class> ptr = ??? arg ???
}

void starter_function() {
  std::shared_ptr<my_class> ptr = std::make_shared<my_class>();

  unsigned long arg = ??? ptr ???
  // pass to library so it may be used by callback
}
Run Code Online (Sandbox Code Playgroud)

目前我在shared_ptr上使用get()然后使用C样式转换,但是当start_function超出范围时会产生问题.

Mar*_*ica 9

创建一个静态存储(可以基于std::map<unsigned long, std::shared_ptr<T>>).提供以下功能:

  • 在商店中注册一个共享指针(将其保存在地图中,并返回一个唯一的长整数).
  • 检索shared_ptr对应于特定的unsigned long
  • 删除特定的unsigned long

(最后两个功能可以组合).

这有吸引力,不需要在指针和unsigned long之间进行任何狡猾的转换,并且(如果返回值基于您测试唯一性的递增计数器),使得更容易找到创建一个对象的问题,删除,然后在同一地址创建另一个对象.

这是一个想法的草图:(特别注意,它不是线程安全的!)

template typename<T>
class Store
{
    static std::map<unsigned long, std::shared_ptr<T>> store;
    unsigned long h;
    bool contains(unsigned long i)
    {
        return store.find(i) != store.end();
    }
 public:
    unsigned long save(const std::shared_ptr& ptr)
    {
        if (store.size() >= std::numeric_limits<unsigned long>::max())
        {
            // Handle error.  Only possible if 64 bit program with
            // 32 bit unsigned long.
        }
        // find an unused handle.
        do
        {
            ++h;
        } 
        while(contains(h));  // Not a good approach if there are main long-lived objects, and h might wrap.
        // Store and return handle.
        store[h] = ptr;
        return h;
    }

    std::shared_ptr<T> retrieve(unsigned long handle)
    {
       if (!contains(handle))
       {
           // handle error
       }
       const auto result = store[handle];
       store.erase(handle);
       return result;
    }
 };
Run Code Online (Sandbox Code Playgroud)