首先:我搜索了网络的一半以找到this作为最接近的解决方案的答案。然而,这对我来说太重了,但我看起来有点不那么复杂了。
那么,一些上下文:我正在构建一个系统,该系统应该能够处理来自队列的传入消息,然后将这些消息的结果存储在另一个队列中。我想将这些响应存储在泛型类中,因为我将它存储在multimap
。
响应类目前定义如下
class COutboundMsg
{
public:
enum eTypeHint {
thNone,
thSomeType,
thLast
};
eTypeHint m_TypeHint;
void* m_OutboundData;
COutboundMsg(COutboundMsg::eTypeHint TypeHint, void* data);
};
COutboundMsg::COutboundMsg(COutboundMsg::eTypeHint TypeHint, void* data) :
m_TypeHint(TypeHint),
m_OutboundData(data)
{
}
现在,目前的工作方式是让用户做这样的事情:
CSomeType* data = new CSomeType();
COutboundMsg(COutboundMsg::thSomeType , (void*) data);
由另一端的用户将void*
强制转换回CSomeType*
(使用类型提示)并删除它。
它不喜欢它。
我宁愿将m_OutboundData包含在auto_ptr
或其他内容中,并确保在完成后删除它。
有什么想法吗?也许完全不同的方法
答案 0 :(得分:3)
通常,多态性用于这样的系统;可以放入出站队列的任何项都派生自QueueItem
,队列包含QueueItem*
或指向QueueItem
的智能指针。
由于这些项都来自公共库,因此您可以安全地删除QueueItem*
或允许智能指针来处理它。这种方法还允许您使用dynamic_cast
来确保指针实际上指向您认为类型的对象。
如果可以采用这种方法,请确保将QueueItem
析构函数设为虚拟,否则将不会调用派生类的析构函数。
答案 1 :(得分:2)
shared_ptr
存储用于删除对象的删除器,因此不依赖于删除时指针的静态类型。所以这样的事情应该做正确的事情:
COutboundMsg(eTypeHint TypeHint, shared_ptr<void> msg);
shared_ptr<CSomeType> data(new CSomeType);
COutboundMsg(COutboundMsg::thSomeType, data);
答案 2 :(得分:1)
如果事先知道消息集(发送/接收),而不是多态,请考虑变体类型,我将专门讨论boost::variant<>
。
这种方法的优点是每条消息都是一个特定的类型(我知道你似乎不想实现它 - 但作为一个长期的设计功能,我想你呢'我会发现这种方法是可扩展的,并且该变体描述了一组消息,让我展示一个简单的例子:
假设我有两条消息
struct Logon{};
struct Logout{};
我定义了一个变体来保存可能的消息集,在给定的时间它只是其中之一..
typedef boost::variant<Logon, Logout> message_type;
现在我可以将它存储在任何容器中,并像往常一样传递它,唯一的区别是访问它们的真正通用方式是通过访问者,例如。
struct process : boost::static_visitor<>
{
void operator()(Logon const& cLogon)
{
// do stuff
}
void operator()(Logout const& cLogout)
{
// do stuff
}
};
// method that processes a given message
void processMessage(message_type const& cMsg)
{
// don't know what this message is, that's fine, hand it to the visitor
boost::apply_visitor(process(), cMsg); // the correct overload will be called for the message
}
......我认为它比void*
稍好一点;)