【问题标题】:Getting the name of sub class within super class in Qt在Qt中获取超类中子类的名称
【发布时间】:2014-01-07 18:08:38
【问题描述】:

我有一个由两个子类继承的基类。所有三个类都使用 qDebug() 进行一些调试打印,并使用 Q_FUNC_INFO 来识别打印源。问题是从基类打印时,Q_FUNC_INFO 包含基类的名称,因此无法知道实例代表两个子类中的哪一个。

到目前为止,我想出的最佳解决方案是在基类中使用 QString 变量而不是 Q_FUNC_INFO,并在实例化时为其提供正确的名称。

还有其他更好的解决方案吗?

【问题讨论】:

    标签: c++ qt qstring qtcore qdebug


    【解决方案1】:

    还有其他更好的解决方案吗?

    一般来说,不,这很好。在这种情况下,如果可能的话,您需要将 Q_FUNC_INFO 放入子类中。如果不是,那你就不走运了,但是……请继续阅读。

    Qt 内部也使用显式字符串而不是 Q_FUNC_INFO,我相信部分是因为这个原因。

    对于QObjects,你可以使用元对象编译器进行一些内省来动态获取真实名称,即:

    const char * QMetaObject::className() const

    返回类名。

    const QMetaObject * QObject::metaObject() const [虚拟]

    返回一个指向该对象元对象的指针。

    元对象包含有关继承 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。在这种情况下,我建议将打印内容放入子类而不是基类中。

    【讨论】:

    • 这只适用于1级深度的继承,尝试从Foo中的baz方法中获取派生自Bar的类的类名
    猜你喜欢
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多