我有一个旧的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超出范围时会产生问题.
创建一个静态存储(可以基于std::map<unsigned long, std::shared_ptr<T>>).提供以下功能:
shared_ptr对应于特定的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)