Reputation: 5459
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
Upvotes: 2
Views: 7046
Reputation: 39906
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.
Upvotes: 1
Reputation: 320551
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.
Upvotes: 0
Reputation: 46617
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.
Upvotes: 12