2015-04-06 36 views
0

我在KDE软件中遇到过一些情况,其中一个是KPart的dynamic_cast在OS X上失败。我不是一个C++专家,所以我甚至不知道从哪里开始调试这样一个情况。 我已经看到这种情况发生与ktimetracker,以及最新的(和更好的讨论)情况是Okular中:https://bugs.kde.org/show_bug.cgi?id=345765当dynamic_cast失败时,这意味着什么?

一言以蔽之:在Okular::Part类继承的类Okular::ViewInterface(作为最后一个父列表中的)。然而当代码检索到Okular::Part*实例(part)时,dynamic_cast<Okular::ViewInterface*>(part)返回NULL。

上面BKO票券的最后一个评论是,在这种情况下使用静态转换将是一个穷人的修复,但是我应该尝试弄清楚为什么dynamic_cast失败。这导致我有2个问题:

  • 除了这里的传统演员,dynamic_cast还有什么作用?
  • 我该如何找出失败的原因?这将是运行时,libC++,否的问题?
+0

在铸造班级时,某种原因喜欢(仿佛)铸造结构的程度如何?我想,真正重要的是类变量,而不是类的功能? – RJVB 2015-04-09 19:13:21

回答

0

Thiago Macieira就Qt利益ML提供了让我解决问题的答案。我在这里将其复制:

在这个 这类问题通常犯罪嫌疑人是一样的:你的虚拟表不正确固定在 共享库。

确保参加这个派对的所有类检查所有这些框:
*必须在类声明的出口宏
*主虚拟功能是一个.cpp,NEVER直列

主要虚函数是 父类的顺序中的第一个新覆盖的函数,或者如果没有被覆盖,则为第一个新虚函数。 通常,多态类具有虚拟析构函数,而且破坏函数总是被覆盖,所以这是最好的选择。

在这种情况下,问题是由于目标类(Okular :: ViewerInterface)未在OS X上导出(可能默认情况下或因为Linux上的全局编译器开关)。同样适用于KDocumentViewer类,但可能不相关。

1

这意味着指针指向的对象的继承层次结构中没有Okular::Part(我忽略了涉及多继承的某些边案例)。因此,动态投射失败。

这就是这个意思。尽管如此,它并不能真正帮助您理解最初引用的错误。

+0

唉唉 类Okular中::部分:公共的KParts :: ReadWritePart,公共Okular中:: DocumentObserver,公共KDocumentViewer,公共Okular中:: ViewerInterface {} 但实例代码试图做的dynamic_cast是的KParts :: ReadWritePart * 。我不能以任何方式看到Okular :: ViewInterface的后代。 如果我的理解正确,那将解释这个问题? – RJVB 2015-04-06 21:50:50

+0

如果是这样,问题(几乎)变成:为什么在Linux上这不会失败?我在OP中没有提到它,但它在那里工作,使用gcc和clang。这也解释了为什么我想到libC++:这是我能想到的唯一相关的事情。但那是检查的运行时间,我认为? – RJVB 2015-04-06 21:54:02

+0

是的,dynamic_cast在运行时进行评估。但是,请注意,这种动态转换可能会成功的一种方式是,如果不同的类将Okular :: ViewInterface和dynamic_cast所属的类分开来。 – 2015-04-06 22:13:55

1

除了这里的传统演员,dynamic_cast还有什么功能?

它执行运行时检查转换是否有效;指针确实指向正确类型的对象。

我该如何弄清楚为什么它会失败?

如果Part真的是从ViewInterface衍生,那么就不能失败,如果指针指向一个有效Part对象。所以对象必须已经被破坏或者被破坏。像Valgrind这样的动态分析工具可以帮助诊断这类问题。

这将是运行时的问题,libC++,no?

几乎肯定不是。这很可能是管理对象的生命周期的问题,最后是一个悬挂指针。或者它可能是一个其他地方破坏对象的错误,所以它不再包含有效的RTTI信息。或者,因为似乎涉及到线程,也许它没有足够的同步而被共享。

静态投将是一个穷人的修复

它不会解决任何事情。您将以不同的方式获得不确定行为的不同风格。

相关问题