首页 > 解决方案 > 使用 Qt 的元对象系统获取对象实例类名

问题描述

我有 3 节课:

class Being : public QObject {
    Q_OBJECT
public:
    explicit Being(QObject *parent = nullptr);
};

class Animal : public Being {
    Q_OBJECT
public:
    explicit Animal(QObject *parent = nullptr);
};

class Dog : public Animal {
    Q_OBJECT
public:
    explicit Dog(QObject *parent = nullptr);
};

存在的实现如下:

Being::Being(QObject *parent) : QObject(parent) {
    qDebug() << staticMetaObject.className();
}

我有以下代码:

Being *pBeing = new Being();
Being *pAnimal = new Animal();
Being *pDog = new Dog();

问题是:有没有办法实现Being的构造函数,以便我可以访问指向我的Being基类的实际实例,以便上述代码的日志为:

Being
Animal
Dog

?

编辑: 我的意图是我希望能够拥有一个Animal.txt,Being.txt并将Doc.txt在 Being 基类中处理。而且我需要知道,根据实例的类型,我是否需要 parseAnimal.txtBeing.txt获取Doc.txt更多信息。

Qt 支持这个吗?有没有一种机制我可以使用 C++/Qt 来实现这一点?如果没有,是否有任何优雅的妥协解决方案?

标签: c++qtqt5qmetaobjectqmetatype

解决方案


在构造函数中是不可能的,Being因为尚未构造封闭对象,因此有关它的元数据不可用。但是,您可以编写在initialize对象构造后应该调用的方法,例如使用 print 函数:

class Being : public QObject {
    Q_OBJECT
public:
    explicit Being(QObject *parent = nullptr) { qDebug() << this->metaObject()->className(); }  // this will always print "Being"
    void initialize() { qDebug() << this->metaObject()->className(); }  // this will print the actual class name
};

class Animal : public Being {
    Q_OBJECT
public:
    explicit Animal(QObject *parent = nullptr) { initialize(); }  // you can already use this method in the constructor
};

TEST(xxx, yyy)
{
    Being* being = new Being();
    Being* animal = new Animal();
    being->initialize();
    animal->initialize();  // or you can call it later
}

如果initialize方法不是很好的解决方案,你总是可以通过Being构造函数来破解它:explicit Being(QString name, QObject* parent = nullptr;然后explicit Animal(QObject *parent = nullptr): Being("Animal") {},但我认为它不太优雅。


推荐阅读