微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过接口复制事件对象

如何解决通过接口复制事件对象

我目前正在做一个小项目并添加一个事件系统。我正在尝试推迟事件,以便它们可以在更新阶段的事件部分进行处理。但问题是我不知道如何从 Event* 复制或创建 Event&

这是问题的简化版本:

#include <list>
#include "Event.h"

std::list<Event*> queue;
Event* buffer;

void PushEvent(Event& e) {
    // copy Event in to some ptr. (This is the code I don't kNow how to write)
    // It doesn't work because Event is an abstract type 
    Event* event = new Event(e);
    queue.push_back(event);
}

Event& PopEvent() {
    buffer = queue[0];
    queue.erase(0);
    return *buffer;
}

bool IsEmpty() {
    return queue.empty();
}

我真的很想保持 API 不变,但我不确定如何复制引用。

提前致谢。

解决方法

问题在于基类不知道如何动态复制其子类的构造实例。相反,Event 接口需要为子类公开一种通用方法来定义如何复制自己,该操作通常称为“克隆”。

您可以使用以下方法:

class Event {
...

public:
    virtual Event * clone() = 0;

...
}

每个子类必须实现 clone 以使用其复制构造函数返回当前实例的副本:

class ChildEvent {
public:
    virtual ChildEvent * clone() {
        return new ChildEvent(*this);
    }

...
}

然后您的用例将如下所示:

Event* event = e.clone();

(顺便说一句,在这些情况下使用 ::std::unique<>() 通常是好的,而不是仅仅返回一个原始指针,但我会留给你)

,

我不认为多态复制事件对象是您真正需要的(尽管这会起作用),而是将这些事件对象的所有权传入和传出事件队列。 >

很可能,事件是在某处生成的,然后存储在事件队列中。最终,存储在队列中的事件被提取并传递给其他组件,这些组件将处理它们或将它们进一步转发以供使用。

我想说的是,Event 对象的这种传输以及它们的所有权如何因移动它们而受到影响是您需要关注的。


首先,我会在队列中从 Event * 切换到 std::unique_ptr<Event> 以明确说明谁拥有事件对象:

std::list<std::unique_ptr<Event>> queue;

这清楚地表明 queue 拥有它所持有的 Event 对象。

PushingEvent() 将使用 std::unique_ptr<Event> 而不是 Event&

void PushEvent(std::unique_ptr<Event> event) {
   queue.push_back(std::move(event));
}

此函数的调用者最初拥有 Event 对象,但在调用它时必须将所有权转移给此函数。然后,PushEvent() 通过进一步将 Event 移入队列,将 std::unique_ptr<Event> 的所有权转移到事件队列。

PopEvent() 类似——只是方向相反:

[[nodiscard]] std::unique_ptr<Event> PopEvent() {
   auto event = std::move(queue.front());
   queue.pop_front();
   return event;
}

事件队列最初拥有要弹出的 Event 对象。它通过局部变量 event 将事件的所有权从队列转移到函数本身。最后,通过按值返回 PopEvent(),所有权进一步转移给 调用者std::unique_ptr<Event>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。