这是我的消息结构:
struct tEventMessage
{
// Type of the event
int Type;
// (void*) Allows those to be casted into per-Type objects
void *pArgument1;
void *pArgument2;
};
我可以向这个结构中添加某种"template"成员吗,以便稍后在构建消息时我可以传递那些指针 + 和我希望的任何其他数据? (见下面的例子)
struct tEventMessage
{
// Type of the event
int Type;
// (void*) Allows those to be casted into per-Type objects
void *pArgument1;
void *pArgument2;
// Template
T tSomeTemplateMember;
};
void HandleClick(....)
{
CVector3 vNewPosition = ....
tEventMessage _msg;
_msg.Type = xxxx;
_msg.pArgument1 = pA->GetObjectPointer();
//
// Wrong!
// Because this CVector3 will not be alive in next tick
// - my pointer will point to nothing.
//
_msg.pArgument2 = static_cast<CVector3*>(&vNewPosition)
//
// Something like that would be great
// And would allow me to use CVector2,CVector3,CVector4 with one template member
//
_msg.tSomeTemplateMember = vNewPosition;
}
最佳答案
我认为你把问题复杂化了。不再是一个问题,如何在消息中传递任意数据,现在您有两个问题,如何处理模板。
实现这类事情的常用方法是使用继承:-
class Message
{
public:
int Type () { return type; }
protected:
int type;
};
class ClickMessage : public Message
{
public:
ClickMessage () { type = ClickMessageID; }
private:
// the message data
};
void HandleMessage (Message *message)
{
switch (message->Type ())
{
case ClickMessageID:
HandleClick (reinterpret_cast <ClickMessage *> (message));
break;
default:
// unhandled message error
break;
}
}
void HandleClick (ClickMessage *message)
{
// do stuff
}
问题是您最终会重复大量代码,即 switch 语句中的强制转换。还有一个维护问题——添加新消息需要仔细更新。您可以稍微破解代码并使用函数指针和映射将消息类型转换为函数并替换 switch 语句。
可能有一个聪明的模板解决方案,但我想不出它可能是什么。
使用 RTTI 可能会有所帮助(有代价)。
这是反射非常擅长解决的问题!
关于结构中的 C++ 模板类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13185677/