У меня есть базовый класс, который наследуется двумя подклассами. Все три класса используют qDebug () для отладочной печати и Q_FUNC_INFO для определения источника печати. Проблема заключается в том, что при печати из базового класса Q_FUNC_INFO содержит имя базового класса, что делает невозможным узнать, какой из двух подклассов представляет экземпляр.
Наилучшее решение, которое я нашел до сих пор, — это использование переменной QString вместо Q_FUNC_INFO в базовом классе и предоставление ему правильного имени при создании экземпляра.
Есть ли другие, более предпочтительные решения?
Есть ли другие, более предпочтительные решения?
В общем, нет, это нормально. В таких случаях вам нужно будет поместить 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
Возвращает метаданные для конструктора с заданным индексом.
#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 только для этой простой вещи. Я бы предложил в таком случае просто поместить отпечаток в подклассы, а не в базовые классы.
Других решений пока нет …