【发布时间】:2015-06-26 00:36:57
【问题描述】:
我有一个使用 SDL 的 C++ 项目,尤其是 SDL 事件。我想将事件系统用于传入的网络消息,就像它用于 UI 事件一样。我可以定义一个新的事件类型并附加一些任意数据(参见this example)。如果我使用普通指针,我会这样做:
Uint32 message_event_type = SDL_RegisterEvents(1);
/* In the main event loop */
while (SDL_Poll(&evt)) {
if (evt.type == message_event_type) {
Message *msg = evt.user.data1;
handle_message(msg);
}
}
/* Networking code, possibly in another thread */
Message *msg = read_message_from_network();
SDL_Event evt;
evt.type = message_event_type;
evt.user.data1 = msg;
SDL_PostEvent(evt);
到目前为止,我一直在使用shared_ptr<Message>。消息在构造后是只读对象,在处理时可能会在很多地方使用,所以我想为它们使用 shared_ptr。
我想在网络端和事件处理端对消息使用 shared_ptr。如果我这样做:
// in networking code:
shared_ptr<Message> msg = ...
evt.user.data1 = msg.get();
// later, in event handling:
shared_ptr<Message> msg(evt.user.data1);
那么有两个独立的 shared_ptrs 并且任何一个都可以删除 Message 对象,而其中一个仍在使用它。我需要以某种方式通过 SDL_UserEvent 结构传递 shared_ptr,该结构只有几个 void * 和 int 字段。
附加。注意SDL_PostEvent 立即返回;事件本身被放入队列中。在消息的 shared_ptr 超出网络代码的范围之后,处理程序可能会从队列中弹出事件。所以我不能传递本地 shared_ptr 的地址来复制。到复制发生时,它可能不再有效。
有没有人遇到过类似的问题并知道一个好的解决方案?
【问题讨论】:
-
为什么是 shared_ptr,为什么不让另一个类创建和删除它们并在需要时将它们作为参考传递?
-
传递一个指向
shared_ptr的指针,并在接收函数中复制它的值。例如。evt.user.data1 = &msg;和shared_ptr<Message> msg = *reinterpret_cast<shared_ptr<Message>*>(evt.user.data1);. -
@JonathanPotter:对于在事件发布功能返回之前进行复制的情况,这似乎是一个很好的解决方案。但它不能。该事件必须存在于队列中,当它被弹出时,原来的 shared_ptr 很可能已经消失了。
-
@Edmund:听起来你需要推出自己的引用计数系统,而不是依赖
shared_ptr对我来说(尽管如果引用计数可以按照@EyasSH 下面的建议手动增加,那么 shared_from_this 可以是一种选择)
标签: c++ sdl shared-ptr