首页 文章

句柄的引用计数而不是指针

提问于
浏览
2

C 11引入了像std :: shared_ptr这样的智能指针 . 该类存储指针和引用计数器 . 当引用计数器达到零时,将调用回调(删除器) . 我的问题是C 11是否有一种简单的方法来使用没有指针的std :: shared_ptr的引用计数器 .

我使用一个c风格的库,它给我一个整数句柄来指定东西 . 我想创建包装句柄的类 . 我想通过使用shared_ptr来避免间接,而我想要一些类型的引用计数来在不再需要时关闭句柄 . 如果你可以使用 createHandle / destroyHandle 创建/销毁句柄,我认为它看起来像这样:

class WrapperClass
{
public:
    WrapperClass() :
        mHandle(createHandle(), &destroyHandle)
    {
    }
private:
    shared_data<int> mHandle;
}

要么

class WrapperClass
{
public:
    WrapperClass() :
        mHandle(createHandle()),
        mRefCount([this](){destroyHandle(mHandle);})
    {
    }
private:
    int mHandle;
    reference_counter mRefCount;
}

另一个问题是,我不确定是否有可能有像 const 这样的工作说明符 . 我的意思是,如果不使用强制转换,就无法删除 const -specifier . 我认为没有办法做到这一点 .

1 回答

  • 1

    通过一些预防措施,您可以尝试使用原始shared_ptr执行此任务:

    #include <iostream>
    #include <memory>
    
    int create_handle() {
        std::cout << "alloc\n";
        return 42;
    }
    
    void delete_handle(int handle)
    {
        std::cout << "delete " << handle << "\n";
    }
    
    
    class Wrapper
    {
    public:
        Wrapper():
            _d(Wrapper::create_handle(), &Wrapper::delete_handle)
        {}
    
        int value()
        {
            return reinterpret_cast<uintptr_t>(_d.get());
        }
    
    private:
        std::shared_ptr<void> _d;
    
        static void* create_handle()
        {
            static_assert(sizeof(create_handle()) <= sizeof(void*), "can't fit");
            static_assert(alignof(create_handle()) <= sizeof(void*), "can't align");
            return reinterpret_cast<void*>(static_cast<uintptr_t>(::create_handle()));
        }
    
        static void delete_handle(void* handle)
        {
            return ::delete_handle(reinterpret_cast<unintptr_t>(handle));
        }
    };
    
    int main()
    {
        Wrapper w;
        std :: cout << w.value();
    }
    

    我相信你必须确保你的句柄可以表示为指针(匹配大小和对齐) . 然后你可以申请 reinterpret_cast 黑魔法 . 因为你基本上只是使用重新解释转换将 int 转换为指针并返回,但从不取消引用指针,它应该是安全的

相关问题