在C++(Qt)中实现内省

4
我想知道是否有人能为我澄清以下问题。我即将参加与Qt相关的测试,样例问题相当模糊。其中一个问题如下所示:
Qt通过什么方式在c++中实现内省:
a. 自动将每个类定义为QObject。
b. 定义可以在QObject类中调用自身的元对象。
c. 为每个QObject定义一个元对象。
我知道要进行内省,必须继承QObject(这也实现了信号和槽),并使用Q_OBJECT宏使其可以被MOC替换。我感觉可能是这三个答案中的任何一个,但我想让别人澄清一下。我认为是A,但我可能错了。
非常感谢您的帮助。

1
如果您有Qt开发环境,我建议查看生成的moc文件,并在Q_OBJECT宏添加时进行检查。 - ratchet freak
3个回答

2
Qt通过在QMetaObject中存储有关每个QObject派生类(以及具有Q_OBJECT宏的类)的信息来实现内省(请阅读这里)。 QMetaObject由moc预处理器构建。
我认为你提供的三个选项都不正确:
1. a是完全错误的。 2. b作为一个句子没有意义。 3. 如果在结尾处添加子类,c则是正确的。
关于moc还有一些更多的信息在这里

非常感谢您的意见,我完全同意您关于子类添加到末尾的观点,这样做更加合理。 - PaulEx10

0

正确答案是C。

  • A:Qt并不会让每个类都继承自QObject(你必须显式地这样做);
  • B:我不确定这是什么意思,但对象不能调用自己,因为C++本身没有内省,这就是为什么...;
  • C:是正确的。它由Q_OBJECT宏处理,该宏标记一个类为MOC(Qt的元对象编译器),以便为该标记类生成关联的QMetaObject常规C++代码。每个QObject存储指向其自己的QMetaObject实例的指针和指向静态QMetaObject实例的第二个指针,该静态实例包含有关其类的信息。

你最后一个观点是错误的,根据 QMetaObject 的文档:“对于在应用程序中使用的每个 QObject 子类,都会创建单个 QMetaObject 实例,并且此实例存储 QObject 子类的所有元信息。该对象可作为 QObject::metaObject() 提供。” 因此每个类只有一个 QMetaObject 实例。 - cmannett85
这是正确的。我提到了“第二个指针”,而不是“第二个实例” - 因为在大多数情况下它是指相同的实例,但并非在每种情况下都是如此 - 执行示例代码:http://pastebin.com/kefegRE7 - Fenix Voltres
当然,该示例无效,因为调用静态成员不是多态的,所以您的第一行返回您期望的内容,但第二行返回QQuickItemQMetaObject。我在Qt源代码中找不到任何您所说的示例。 - cmannett85

0

出于效率的考虑(我猜),Qt并没有像Java或.NET那样从一个共同的基类派生每个类型。

QObject公开了QMetaObject,它确实允许大量的反射编程,但最基本的元编程工具是QMetaType

事实上,一些经常使用的类,如QPen或QSize,它们是“根”对象,即根本不从任何东西派生,或者您自己的类,可以通过宏Q_DECLARE_METATYPE提供给元编程。

目的是使QVariant能够构建和复制通用对象。然后,由于属性交换或方法调用已在系统级别上定义,因此可以使用QVariant将这些对象充分利用。

这是一种“混合”的高效架构,有时需要硬编码接口到文字。通用接口可用,但仅适用于二进制数据。再次出于效率考虑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接