Question

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

Was it helpful?

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.

OTHER TIPS

The only way for an upcast to return null-pointer is when you pass a null-pointer as an argument for the cast.

The second possibility is this case is that your are thinking that you are performing an upcast, while in reality it is not an upcast. You haven't shown any code that calls the function with the cast, so there's no way to say what is happening there.

Looking at your code: there's no upcast in your code. What you are trying to do is a downcast. And the argument you passed to the function is passed by value, which means that it got sliced in the process. No wonder the downcast fails. It should fail. You have to pass either by pointer or by reference to use dynamic_cast.

P.S. Don't use HTML tags to format code on SO. Use the "Code" button.

dynamic_cast<> returns NULL if the types between you are wanting to cast are unrelated, or if you have provided it a NULL pointer to cast. The checking is performed at run-time, on the type info provided thanks to the RTTI, and you can trust it.

So there's these two possibilities only.

Either eventArgs is not a AtsCommandEventArgs or eventArgs references a to NULL.

Like others have noticed, you pass the eventArgs by value, so the AtsCommandEventArgs part of the object is not copied to. As others have told you, pass the AtsCommandEventArgs by pointer or by references.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top