0

我正在编写一个需要在彼此之间交换消息的对象的软件。消息必须具有以下内容:

Peer *srcPeer;
const char* msgText;
void* payload;
int payLoadLen;

现在,Peer 必须是一个指针,因为我有另一个管理 Peers 的类。剩下的我很怀疑......例如,我可以在创建消息时复制消息文本和有效负载(通过分配两个新缓冲区),然后将删除放在消息的析构函数中。这具有避免忘记消费者函数中的删除的巨大优势(没有提到使这些函数更简单),但它会导致许多分配和复制,并且会使一切变慢。所以我可能只是分配指针并且仍然让析构函数删除一切......或者......这是一种常见的情况,在其他编程语言中甚至不是两难选择,因为有 GC。你有什么建议,最流行的做法是什么?

编辑:我的意思是我想知道传递内容的最佳实践是什么......比如拥有另一个跟踪它们的对象,或者可能是共享指针......或者你会做什么......

4

7 回答 7

2

你需要清楚ownership:当消息在对等点之间传递时,所有权是否改变了?如果您切换所有权,只需让接收方进行清理即可。

如果您只是“出租”一条消息,请确保有一个“归还所有者”程序。

消息是否共享?然后你可能需要一些复制有互斥锁来保护访问。

于 2009-11-25T17:52:29.607 回答
1

如果所有消息都相似,请考虑使用垃圾堆栈(http://library.gnome.org/devel/glib/stable/glib-Trash-Stacks.html) - 这样,您可以保留一个已分配的堆栈 -尚未初始化的消息结构,您可以重用它们,而不会受到持续的 malloc/free 命中。

于 2009-11-25T17:51:53.260 回答
0

考虑使用shared_ptr<>, 可从 Boost 获得,也是std::tr1库的一部分,而不是原始指针。这不是在所有情况下都最好使用的东西,但看起来你想让事情变得简单,而且它非常擅长。这是本地引用计数垃圾收集。

于 2009-11-25T17:53:42.970 回答
0

在 C++ 中对此没有任何规则甚至最佳实践,除非您对指针所有权做出设计决定并坚持下去。

您可以尝试通过使用智能指针来执行特定的策略,或者您可以简单地记录设计的行为并希望每个人都阅读手册。

于 2009-11-25T17:54:13.380 回答
0

在 C++ 中,您也可以进行引用计数,如下所示:

http://library.gnome.org/devel/glibmm/stable/classGlib_1_1RefPtr.html

在这种情况下,您可以传递 Glib::RefPtr 对象。当与指针关联的这些 RefPtr-s 中的最后一个被销毁时,对象本身将被删除。

如果你不想使用 glibmm,你也可以实现它,这不是太难。此外,可能 STL 和 boost 也有类似的东西。

请注意循环引用。

于 2009-11-25T17:56:11.847 回答
0

最简单的做法是使用对象来管理缓冲区。例如,您可以std::string同时使用msgTextandpayload成员,并且您可以取消 the payLoadLen,因为它会由该payload.size()方法处理。

当且仅当您测量此解决方案的性能以及复制的行为msgText导致payload不可接受的性能损失时,您可能会选择使用指向由消息副本共享的结构的共享指针。

在(几乎)任何情况下,我都不会依赖于记住调用delete析构函数或手动编写安全的复制赋值运算符和复制构造函数。

于 2009-11-25T17:56:16.450 回答
0

最简单的处理策略是复制整个消息(深拷贝)并将该副本发送给收件人。这将需要更多的分配,但它使您摆脱了与并发访问数据相关的许多问题。如果性能变得至关重要,则仍有一些优化的空间(例如,如果对象只有一个愿意在发送时放弃其所有权的所有者,则避免复制等)。

然后每个所有者负责清理消息对象。

于 2009-11-25T17:57:52.683 回答