Получение имени подкласса в суперклассе в Qt

У меня есть базовый класс, который наследуется двумя подклассами. Все три класса используют qDebug () для отладочной печати и Q_FUNC_INFO для определения источника печати. Проблема заключается в том, что при печати из базового класса Q_FUNC_INFO содержит имя базового класса, что делает невозможным узнать, какой из двух подклассов представляет экземпляр.

Наилучшее решение, которое я нашел до сих пор, — это использование переменной QString вместо Q_FUNC_INFO в базовом классе и предоставление ему правильного имени при создании экземпляра.

Есть ли другие, более предпочтительные решения?

3

Решение

Есть ли другие, более предпочтительные решения?

В общем, нет, это нормально. В таких случаях вам нужно будет поместить Q_FUNC_INFO в подкласс, если это возможно. Если нет, вам не повезло, но … пожалуйста, продолжайте читать.

Внутри Qt также используются явные строки, а не Q_FUNC_INFO, я полагаю, частично по этой причине.

Для QObjects вы можете использовать мета-объектный компилятор для некоторого самоанализа, чтобы динамически получить настоящее имя, а именно:

const char * QMetaObject :: className () const

Возвращает имя класса.

а также

const QMetaObject * QObject :: metaObject () const [виртуальный]

Возвращает указатель на мета-объект этого объекта.

Мета-объект содержит информацию о классе, который наследует QObject, например, имя класса, имя суперкласса, свойства, сигналы и слоты. Каждый подкласс QObject, который содержит макрос Q_OBJECT, будет иметь мета-объект.

Информация мета-объекта требуется механизмом соединения сигнал / слот и системой свойств. Функция Legits () также использует мета-объект.

Если у вас нет указателя на фактический экземпляр объекта, но вы все еще хотите получить доступ к мета-объекту класса, вы можете использовать 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 только для этой простой вещи. Я бы предложил в таком случае просто поместить отпечаток в подклассы, а не в базовые классы.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]