C++向下转型(使用dynamic_cast)返回NULL?

发布于 2024-09-16 02:55:57 字数 1973 浏览 5 评论 0原文

环境:Linux C++ / Qt 4x

我不明白为什么下面的向下转型返回NULL?我在下面粘贴了基类和派生类。

预先感谢您的任何提示或建议。

-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;
};

预先感谢您提供任何提示或建议,

-Ed

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦里寻她 2024-09-23 02:56:04

向上转换返回空指针的唯一方法是传递空指针作为转换的参数。

第二种可能性是,您认为自己正在执行向上转换,而实际上它不是向上转换。您还没有显示任何使用强制转换调用该函数的代码,因此无法说明那里发生了什么。

查看您的代码:您的代码中没有upcast。你想要做的是沮丧。并且您传递给函数的参数是按值传递的,这意味着它在此过程中被切片。难怪沮丧失败了。它应该失败。您必须通过指针或引用传递才能使用dynamic_cast

PS 不要使用 HTML 标签来格式化 SO 上的代码。使用“代码”按钮。

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.

余厌 2024-09-23 02:56:03

如果您想要转换的类型之间不相关,或者如果您为其提供了一个 NULL 指针来进行转换,则 dynamic_cast 返回 NULL。检查是在运行时根据 RTTI 提供的类型信息执行的,您可以信任它。

所以只有这两种可能。

eventArgs 不是 AtsCommandEventArgs 或 eventArgs 将 a 引用为 NULL。

就像其他人注意到的那样,您按值传递 eventArgs,因此对象的 AtsCommandEventArgs 部分不会被复制到。正如其他人告诉您的那样,通过指针或引用传递 AtsCommandEventArgs。

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.

李白 2024-09-23 02:56:01

您正在按值传递 fes::EventArgs 对象,这意味着它一个 fes::EventArgs 对象。如果要保留多态对象的原始类型,请传递一个指针或(更好)对它们的引用:

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

请注意,如果失败,dynamic_cast 会抛出 std::bad_cast如果应用于参考文献。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文