使用 ascyc c 库时的 RAII

问题描述 投票:0回答:1

我在

cnats
库周围有一个 RAII 包装器。我们不需要了解
cnats
的细节。只有两个重要的部分。
cnats
是用于与 NATS 消息代理通信的 C 客户端。通常情况下,他们的所有结构都有自定义创建和删除功能。

我有一个用于创建

natsMsg
对象的 RAII 包装器。构造函数:

NatsMessage(const std::string& subject, const std::string& data) {
        natsMsg* temp;
        HANDLE_STATUS(natsMsg_Create(&temp, subject.c_str(), nullptr, data.c_str(), data.size()));
        msg = std::shared_ptr<natsMsg>(temp, [](natsMsg* p) {natsMsg_Destroy(p);});
    }

有两个发布功能:

js_PublishMsg
js_PublishMsgAsync
。常规功能只是发布消息。我目前正在添加对异步版本的支持,它接管消息并在完成时调用
natsMsg_Destroy
,导致竞争条件和双重免费错误。

来自阅读

std::shared_ptr

一个对象的所有权只能通过复制构造或复制赋值给另一个shared_ptr来与另一个shared_ptr共享。

std::unique_ptr
有相似的语言。

本质上我的问题是我想将 smart_pointer 与自定义删除器一起使用。当我调用异步发布函数时,我想以某种方式“删除”所有权,以便 c 库处理删除。

我可以切换到

unique_ptr
或其他智能指针(或其他实现此目的的方式)。

c++ raii nats.io
1个回答
0
投票

如果你不需要共享所有权,你可以使用具有

std::unique_ptr
功能的
release()

struct NatsMessage{
    NatsMessage() {
        natsMsg* temp;
        GetMsg(&temp);
        msg.reset(temp);

        // when you need to transfer ownership to C library
        // natsMsg* m = msg.release();
    }

    std::unique_ptr<natsMsg,decltype(&natsMsg_Destroy)> msg = {nullptr, &natsMsg_Destroy};
};

  • 如果你想继续使用

    std::shared_ptr
    ,你可以设置一些标志来禁用删除器。

  • 你也可以使用原始指针并在析构函数中手动释放它,注意这也需要正确处理复制/移动案例。

© www.soinside.com 2019 - 2024. All rights reserved.