Search code examples
c++nulldynamic-cast

C++ downcast ( using dynamic_cast ) returns NULL?


Environment: Linux C++ / Qt 4x

I do not understand why the following downcast returns NULL? I pasted base and derived class below.

Thanks in advance for any tips or suggestions.

-Ed

void MainWindow::onRtledaEventHandler(fes::EventArgs eventArgs)
{
   // This cast returns a NULL ?
   fes::AtsCommandEventArgs* atsCommandEventArgs = dynamic_cast<fes::AtsCommandEventArgs*>(&eventArgs);
}


/// The base class for containing event arguments sent to clients using boost::signals2
class EventArgs
{
public:

   EventArgs() {}
   EventArgs(RtledaEventType eventType) :
         m_eventType(eventType) {}
   EventArgs(const EventArgs& eventArgs) :
         m_eventType(eventArgs.m_eventType) {}
   virtual ~EventArgs() {}

   /// The type of event this is
   RtledaEventType eventType() const { return m_eventType; }

protected:
   RtledaEventType m_eventType;
};

// Derived class I am trying to upcast to
class AtsCommandEventArgs : public EventArgs
{
public:
   /// \param [in] lraddsPacketError LRADDS oacket error structure
   /// \sa fes::StructPacketStats_t packetStats
   AtsCommandEventArgs(fes::AtsCommand atsCommand, std::string messageBuffer, std::string details) :
         EventArgs(RtledaEventTypeAtsCommand),
         m_atsCommand(atsCommand),
         m_messageBuffer(messageBuffer),
         m_details(details) {}

   AtsCommandEventArgs(const AtsCommandEventArgs& AtsCommandEventArgs) :
         EventArgs(AtsCommandEventArgs),
         m_atsCommand(AtsCommandEventArgs.m_atsCommand),
         m_messageBuffer(AtsCommandEventArgs.m_messageBuffer),
         m_details(AtsCommandEventArgs.m_details) {}

   AtsCommandEventArgs() {}
   ~AtsCommandEventArgs() {}

   fes::AtsCommand atsCommand() const { return m_atsCommand; }
   std::string messageBuffer() const { return m_messageBuffer; }
   std::string details() const { return m_details; }

private:
   fes::AtsCommand m_atsCommand;
   std::string m_messageBuffer;
   std::string m_details;
};

Thanks in advance for any tips or suggestions,

-Ed


Solution

  • You are passing a fes::EventArgs object by-value, which means it is a fes::EventArgs object. If you want to preserve the original type of polymorphic objects, pass a pointer or (better) a reference to them:

    void MainWindow::onRtledaEventHandler(fes::EventArgs& eventArgs) {
       fes::AtsCommandEventArgs& atsCommandEventArgs = dynamic_cast< fes::AtsCommandEventArgs&>(eventArgs);
    }
    

    Note that dynamic_cast throws std::bad_cast in case of failure if applied to references.