1

我有 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 来实现这一点?如果没有,是否有任何优雅的妥协解决方案?

4

2 回答 2

2

在构造函数中是不可能的,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") {},但我认为它不太优雅。

于 2020-11-05T14:19:37.200 回答
0

我的意图是我希望能够拥有将在 Being 基类中处理的 Animal.txt、Being.txt 和 Doc.txt。而且我需要知道,根据实例的类型,我是否需要解析 Animal.txt、Being.txt 或 Doc.txt 以获取更多信息。

永远不要让基类知道它的子类。曾经。

不管它看起来多么诱人,都不要这样做(即使你知道怎么做)。

一个类可能有数百个子类。举个例子QObject。应该QObject(或可能)知道您重新实现QMainWindow?

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

可能的解决方案

如果文本文件的处理算法相同,不管子类,创建一个基类方法来做处理,并从子类中调用。

如果算法依赖于子类,则将方法抽象化,即没有virtual实现( =0),并让实现到子类。

于 2020-11-05T15:19:23.317 回答