我正在使用将运行战舰游戏的套接字在C ++中使用基本客户端服务器应用程序。客户端和服务器之间的所有通信都采用简单的对象层次结构,如下所示:
namespace Message {
enum MessageType { BASE, RESULT };
class BattleshipMessage {
public:
virtual MessageType get_type() { return BASE; }
virtual ~BattleshipMessage() {}
};
class ResultMessage : public BattleshipMessage {
public:
char _attackResult;
ResultMessage( char result ) : _attackResult( result ) {}
virtual MessageType get_type() { return RESULT; }
~ResultMessage() {}
};
}
当接收通过套接字发送的对象时,我希望能够将其作为通用BattleshipMessage接收,然后基于get_type()返回的MessageType将其转换为适当的子类以检索我可能的任何其他信息需要处理消息。我担心C#让我变得柔软,因为我已经使用像ResultMessage result = message as ResultMessage
那样的简单语法来完成这种事情,但是我一直试图让我的C ++实现工作。
BattleshipMessage* message;
recv( hAccepted, reinterpret_cast<char*>( &message ), sizeof(message), 0 );
switch ( message->get_type() ) {
case RESULT:
if ( ResultMessage* result = dynamic_cast<ResultMessage*>(message)) {
std::string celebration = "HOORAY!";
}
break;
}
当我取消引用指针并尝试调用get_type()时,我得到Access violation reading location
。有人能指出我正确的方向吗?
答案 0 :(得分:3)
sizeof(message)
给出指针的大小,通常为32位或64位,具体取决于您的机器。你想要
sizeof(BattleshipMessage)
给出了班级的大小。即使这样,我也不确定这是正确的方法,因为每个类对象都包含一个指向vtable的指针,该指针处理动态调度/虚函数调用,并且使用您使用的原始强制转换方法在机器上发送类将无效指针。
我认为您应首先序列化您的对象(即将其转换为字符流),然后再通过网络发送,然后反序列化以重建该类: Is it possible to serialize and deserialize a class in C++?
答案 1 :(得分:0)
删除所有虚拟方法,并将MessageType存储为BattleshipMethod中的成员变量。那么你的代码应该可以工作。