【问题标题】:C++ - object which can be owned or shared in the same classC++ - 可以在同一个类中拥有或共享的对象
【发布时间】:2016-04-19 17:09:33
【问题描述】:

我有一个类 (PackRequest),其中包含一些容器 (EventPack)。根据用途,此容器可以归类对象所有,也可以从某些外部来源提供。

特别是,整个对象被转移到另一个进程,因此必须被序列化。所以在发送过程中,它是从一些外部来源提供的,然后才序列化和传输。在接收过程中,我们必须从序列化数据中恢复它——因此,我们必须创建并拥有它。

我用非常简单的解决方案解决了它,但我不完全喜欢它:

class PackRequest : public Request {
    private:
        unique_ptr<EventPack> owned_pack_;
        EventPack *pack_;

    public:
        PackRequest(EventPack *pack=nullptr)
            : pack_(pack) {}

        void serialize() override;
        void unserialize() override;
};

然后序列化/反序列化函数如下:

void PackRequest::serialize() {
    auto size = pack_->serialized_size();
    data_msg_ = make_unique<zmq::message_t>(size);
    pack_->serialize_bin(data_msg->cdata(), size);
}

void PackRequest::unserialize() {
    owned_pack_ = make_unique<EventPack>();
    pack_ = owned_pack_->get();
    pack_->unserialize_bin(data_msg_->cdata(), data_msg_->size());
}

然后在发送端,owned_pa​​ck_ 是 nullptr,并且 pack_ 在构造函数中提供 - 所以我们不拥有该对象,我们只是将其序列化为 data_msg_ 并发送。在接收端,我们在 data_msg_ 中获得了相同的数据 - 所以我们创建了我们拥有的新对象(保存在 own_pack_ 中),然后从数据中反序列化它。

现在,它可以工作并且很短 - 但我不确定它是否是最好的方法 - 特别是,它使用了我不喜欢的非智能指针。那么你有什么想法更符合现代 C++ 规则吗?

【问题讨论】:

  • 我在考虑使用 shared_ptr 而不是两个指针,因为我们不拥有引用的 EventPack 的情况下人为增加了引用计数 - 但我没有找到手动操作引用计数器的方法在 shared_ptr 中。
  • 我觉得这个问题更适合 Code Review:codereview.stackexchange.com
  • @kompas 当该对象被其他人拥有时,如果该对象在它仍然被指向时不再存在,您希望发生什么?或者你能证明这种情况不会发生吗?
  • @user2079303:我可以保证它不会发生(我知道,这有点冒险,但在这一点上,性能更重要)。

标签: c++ c++11 serialization smart-pointers ownership


【解决方案1】:

由于您可以保证原始指针始终有效(当它被使用时),所以不需要智能指针,您当前的实现就可以了。

另一种选择是在外部源中使用shared_ptr,在PackRequest 中使用单个shared_ptr。这增加了对对象如何存储在外部源中的依赖(必须是shared_ptr)并且对引用计数有一些小的开销,但另一方面,您永远不需要测试哪个指针具有数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 2019-07-10
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    相关资源
    最近更新 更多