在Qt中获取超类中的子类的名称
Getting the name of sub class within super class in Qt
我有一个基类,它由两个子类继承。这三个类都使用qDebug()进行一些调试打印,并使用Q_FUNC_INFO来标识打印的源。问题是,从基类打印时,Q_FUNC_INFO包含基类的名称,因此无法知道实例代表的是两个子类中的哪一个子类。
到目前为止,我提出的最好的解决方案是在基类中使用QString变量而不是Q_FUNC_INFO,并在实例化时为其提供正确的名称。
还有其他更可取的解决方案吗?
还有其他更可取的解决方案吗?
一般来说,不,那没关系。在这种情况下,如果可能的话,您需要将Q_FUNC_INFO放入子类中。如果没有,你就没有运气了,但是。。。请继续阅读。
Qt内部也使用显式字符串,而不是Q_FUNC_INFO,我相信部分原因是这个。
对于QObjects,您可以使用元对象编译器进行一些内省,以动态获取真实名称,即:
const char*QMetaObject::className()const
返回类名。
和
constQMetaObject*QObject::metaObject()const[virtual]
返回指向此对象的元对象的指针。
元对象包含有关继承QObject的类的信息,例如类名、超类名、属性、信号和槽。包含Q_OBJECT宏的每个QObject子类都将有一个元对象。
元对象信息是信号/插槽连接机制和属性系统所需要的。inherits()函数还使用了元对象。
如果您没有指向实际对象实例的指针,但仍想访问类的元对象,则可以使用staticMetaObject。
您在处理构造函数时也会注意到这一点,因为您的评论似乎表明了这一点:
QMetaMethod QMetaObject::constructor(int index)const
返回具有给定索引的构造函数的元数据。
main.cpp
#include <QObject>
#include <QDebug>
class Foo : public QObject
{
Q_OBJECT
public:
virtual void baz() { qDebug() << "Class name:" << metaObject()->className(); }
};
class Bar : public Foo
{
Q_OBJECT
};
#include "main.moc"
int main()
{
Bar bar;
bar.baz();
return 0;
}
输出
moc main.cpp -o main.moc && g++ -Wall -I/usr/include/qt -I/usr/include/ -I/usr/include/qt/QtCore -lQt5Core -fPIC main.cpp && ./a.out
Class name: Bar
注意:如果你想让这个机制在构造函数中工作,简单的答案是你不能。没有什么能真正帮助你。这是由于在C++中继承是如何处理的。首先,基类是构造好的,在这个阶段,子类还没有完全构造好(严格地说,甚至不是基类),所以如果不明确地确保基类构造函数有一个额外的参数,你就无法真正获得更多关于它的信息。但是,仅仅为了这个简单的事情,你就会得到一个膨胀的API。在这种情况下,我建议只将print放入子类中,而不是基类中。
- 创建子类的多个实例,其中只有一个超类实例
- 用初始化列表和超类构造函数声明子类构造函数的正确方式
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- 无法使用子类变量访问超类公共成员
- 如何高效/正确地存储等距游戏的不同类(单个超类的所有子类型)的地图?
- 我可以从我的超类调用子类构造函数吗?
- 子类未能继承超类字段
- 子类/超类的"无匹配函数调用"
- 子类是否也在 c++ 中继承私有数据成员?但通过超类的公共方法访问
- 在子类函数中访问超类友元的受保护数据成员
- cpp 从需要超类对象的函数访问子类对象方法
- 制作可以存储子类对象的超类类型的向量
- 从超类访问子类
- C ++如何使用子类调用函数,具有超类指针
- 在C++中,继承超类的正确方法是什么,以便它们的子类在超级类和子类中没有重复的属性?
- 无法将超类强制转换为子类
- C++ 在超类构造函数中运行依赖于子类覆盖的大量变量的代码的正确方法是什么?
- 将子类列表转换为超类列表
- 在子类的构造函数中调用超类的构造器两次
- 在没有数据重复的情况下强制转换/实例化/转换为子类/超类