使用 Qt 的元对象系统获取对象实例 class 名称

Get object instance class name with Qt's meta-object system

我有 3 个 classes:

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::Being(QObject *parent) : QObject(parent) {
    qDebug() << staticMetaObject.className();
}

我有以下代码:

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

问题是:有没有办法实现 Being 的构造函数,这样我就可以访问指向我的 Being 基的实际实例 class 这样上面代码的日志将是:

Being
Animal
Dog

?

编辑: 我的意图是我希望能够有一个 Animal.txtBeing.txtDoc.txt,它们将在 Being 基础 class 中处理。我需要知道,根据实例的类型,我是否需要解析 Animal.txtBeing.txtDoc.txt 以获得更多信息。

Qt 支持吗?有没有一种机制可以使用 C++/Qt 来实现?如果没有,是否可以对此有任何优雅的折衷解决方案?

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

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") {},但我认为它更少优雅。

My intention is that I want to be able to have a Animal.txt, Being.txt and Doc.txt that will be processed inside the Being base class. And I need to know, based on the instance's type, whether I need to parse Animal.txt, Being.txt or Doc.txt to get more information.

永远不要让基地 class 知道它的子 class 的任何信息。曾经。

无论它看起来多么诱人,都不要去做(即使你知道怎么做)。

一个class可能有数百个子class。以 QObject 为例。 QObject 是否应该(或者可能)了解您对 QMainWindow 的重新实现?

所以,无论这个设计决定的原因是什么,改变它!

可能的解决方案

如果文本文件的处理算法相同,不管subclass,创建一个基础class方法来处理并从sub[=32=调用它]es.

如果算法依赖于subclass,将方法抽象化,即virtual并且没有实现(=0),让实现到subclasses.