从parent到child的dynamic_cast问题

时间:2013-04-21 02:16:21

标签: c++ inheritance polymorphism downcast

我正在使用将运行战舰游戏的套接字在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。有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:3)

sizeof(message)

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

sizeof(BattleshipMessage)

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

我认为您应首先序列化您的对象(即将其转换为字符流),然后再通过网络发送,然后反序列化以重建该类: Is it possible to serialize and deserialize a class in C++?

答案 1 :(得分:0)

删除所有虚拟方法,并将MessageType存储为BattleshipMethod中的成员变量。那么你的代码应该可以工作。