【问题标题】:Casting Pointer of Stack Objects堆栈对象的转换指针
【发布时间】:2017-07-26 00:16:10
【问题描述】:

我正在构建一个消息队列,目前我有两种类型的消息,其中一种使用模板类。

class Message {
public:
    Message() : m_iMessageType( MESSAGE_UNDEFINED ) {}
    Message( int iMessageType ) : m_iMessageType( iMessageType ) {}
    int getType() { return m_iMessageType; }
    void setType( int iMessageType ) { m_iMessageType = iMessageType; }
private:
    int m_iMessageType;
}

template<typename T>
class DataMessage: public Message {
public:
    DataMessage() : Message(), m_oData( T() ) {}
    DataMessage( int iMessageType, T oData ) : Message( iMessageType ), m_oData( oData ) {}
    T getData() { return m_oData; }
    void setData( T oData ) { m_oData = oData; }
}

这让我可以发送这样的消息

Message toMessage( MESSAGE_GET_NAME );
DataMessage<std::string> fromMessage();
Messenger::getMessenger()->sendMessage( &toMessage, &fromMessage, CONSUMER );
std::cout << "Consumer name: " << fromMessage.getData() << std::endl;

但是,这导致我在内部处理消息时进行类型转换(在上面的代码中将Message 转换为适当的DataMessage&lt;std::string&gt;fromMessage)。我的一位消费者可能看起来像这样:

class Receiver {
public:
    Receiver() { Messenger::register( RECEIVER, this ); }
    handleMessage( Message* pIn, Message* pOut ) {
        // Ignoring the usual checking the message type
        (static_cast<DataMessage<std::string>*>( pOut ))->setData( "Consumer1" );
    }

如果指针指向调用方法的堆栈上的对象,那么它是否安全?

如果我尝试以下代码(这是错误的)

Message toMessage( MESSAGE_GET_NAME );
Message fromMessage; // The consumer is going to try and cast this to DataMessage<std::string>
Messenger::getMessenger()->sendMessage( &toMessage, &fromMessage, CONSUMER );

我没有收到任何段错误或错误。是不是出了什么可怕的问题,并且会在执行过程中慢慢出现?

【问题讨论】:

  • 这是函数声明:Message fromMessage();。使用Message fromMessage;Message fromMessage{};
  • 修正了你的两个观点
  • 这是一个可以使用 dynamic_cast 的上下文。如果成功,则无需担心访问指向的对象。只要它在操作期间保持有效,它位于何处都没有关系。

标签: c++ casting message-queue


【解决方案1】:

你在这里问了两个问题。

如果指针指向调用方法的堆栈上的对象,它是否安全?

是的,这是安全的。只要对象确实是您将其转换为的类型,对象的位置就无关紧要。

但是,您使用static_cast 的设计风格并不是很好。如果对象不是提供的类型,dynamic_cast 至少会返回一个空指针。

是不是出了什么可怕的问题,并且在执行过程中会慢慢出现?

是的。您将Message 投射到DataMessage。那是未定义的行为。可能您最终只会读取 Message 对象结束后发生在堆栈上的任何内容。

【讨论】:

    猜你喜欢
    • 2013-08-19
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 2015-11-16
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多