dynamic_cast与动态库边界

时间:2019-07-01 10:53:44

标签: c++

我正在阅读``使用Qt 4进行C ++ GUI编程'',在其中找到以下语句

  

与标准C ++ dynamic_cast()不同,Qt的qobject_cast()可以在动态库边界上正常运行。

类似的声明出现在

的官方Qt文档中

https://doc.qt.io/qt-5/qobject.html#qobject_cast

是什么意思?在哪里我们不能在C ++中使用dynamic_cast? 虚函数呢?将它们与动态链接的库一起使用是否安全?

1 个答案:

答案 0 :(得分:5)

从概念上讲,class myTable1(models.Model): number = models.BooleanField(default=True) date = models.DateField(default=None) class myTable2(models.Model): number = models.BooleanField(default=True) date = models.DateField(default=None) 可以跨模块边界工作。但是,某些编译器/链接器以性能为名偷工减料。加载共享库时提高性能的方法之一是使其他库可见的符号越少越好。这减少了加载程序要做的工作量,因为它不必解析尽可能多的符号。 RTTI符号位于斩波块上,并且默认情况下不在其他模块中。 GCC的文档对此进行了描述,并提供了解决方法here

不幸的是,当涉及到RTTI时,这使事情变得一团糟。构造一个对象的模块和一个执行dynamic_cast的模块可以保留自己的类型的RTTI符号,否则相同。当在不同模块中执行dynamic_cast时,这会使它们显示为不同类型,从而导致dynamic_cast意外返回dynamic_cast或将nullptr用作引用。

在链接和调用std::bad_cast时,加载器需要知道在模块加载时解析模块之间的RTTI符号,因此需要特别注意。

此外,历史上Qt支持platforms,它要么不支持RTTI,要么在RTTI有太多开销的地方。因此,发明了dlopen()来完全消除对RTTI的依赖,同时仍然提供了一种在多态类型之间进行转换的方法。

要回答您的其他问题:

  • 您可以在任何可用的RTTI处使用qobject_cast,但动态链接可能会很困难。
  • 在这些情况下,虚拟函数work fine是由加载程序 解析的功能符号。