使用 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.txt
、Being.txt
和 Doc.txt
,它们将在 Being 基础 class 中处理。我需要知道,根据实例的类型,我是否需要解析 Animal.txt
、Being.txt
或 Doc.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.
我有 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.txt
、Being.txt
和 Doc.txt
,它们将在 Being 基础 class 中处理。我需要知道,根据实例的类型,我是否需要解析 Animal.txt
、Being.txt
或 Doc.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.