3

I'm working on a basic client server application in C++ using sockets that will run a game of battleship. All communication between client and server is in the form of a simple object hierarchy that looks something like this:

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() {}
    };
}

When receiving an object sent through the socket, I would like to be able to receive it as a generic BattleshipMessage and then based on the MessageType returned by get_type() cast it to the appropriate child class to retrieve whatever additional information I might need to process the message. I'm afraid that C# has made me soft as I've done this sort of thing with easy syntax like ResultMessage result = message as ResultMessage however I'm stuck trying to get my C++ implementation working.

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;
}

I get Access violation reading location when I dereference the pointer and try to call get_type(). Can anyone point me in the right direction?

4

2 回答 2

3
sizeof(message)

给出指针的大小,通常是 32 位或 64 位,具体取决于您的机器。你要

sizeof(BattleshipMessage)

它给出了班级的规模。即使那样,我也不确定这是正确的方法,因为每个类对象都将包含一个指向处理动态调度/虚拟函数调用的 vtable 的指针,并且使用您使用的原始强制转换方法跨机器发送类将使该类无效那个指针。

我认为你应该先序列化你的对象(即将它转换为字符流),然后再通过网络发送它,然后反序列化以重建类: 是否可以在 C++ 中序列化和反序列化一个类?

于 2013-04-21T02:20:38.753 回答
0

去掉所有的虚方法,将 MessageType 作为成员变量存储在 BattleshipMethod 中。然后你的代码应该可以工作。

于 2013-04-21T02:32:40.740 回答