
Отладка классов в Qt с помощью QDebug
Работая с классами в Qt вам неоднократно приходилось сталкиваться с отладкой, при этом строчка вида:
qDebug() << value;
Используется очень часто, в том числе, когда нужно контролировать значения некоторых переменных, а запускать отладку долго и не эффективно.
Если же вы хотите вывести значение полей экземпляра класса, тут qDebug() пасует – он попросту ничего не знает о вашем классе и всё, что вы получите в результате - строку вида 0x19e8aa45460.
Сегодня мы рассмотрим перегрузку оператора << для класса CountryFlag для последующего использования в конструкциях вида:
CountryFlag flag; qDebug() << flag;
Создаем класс
Для тестов нам понадобится класс, мы будем использовать созданный в предыдущих статьях CountryFlag:
Заголовок:
#ifndef COUNTRYFLAG_H
#define COUNTRYFLAG_H
#include <QString>
class CountryFlag
{
public:
CountryFlag();
CountryFlag(int id, QString name, QString icon);
QString getIcon() const;
void setIcon(const QString &value);
QString getName() const;
void setName(const QString &value);
int getId() const;
void setId(int value);
private:
int id;
QString icon;
QString name;
};
#endif // COUNTRYFLAG_H
Реализация:
#include "countryflag.h"
CountryFlag::CountryFlag()
{
}
CountryFlag::CountryFlag(int id, QString name, QString icon)
{
this->id = id;
this->name = name;
this->icon = icon;
}
QString CountryFlag::getIcon() const
{
return icon;
}
void CountryFlag::setIcon(const QString &value)
{
icon = value;
}
QString CountryFlag::getName() const
{
return name;
}
void CountryFlag::setName(const QString &value)
{
name = value;
}
int CountryFlag::getId() const
{
return id;
}
void CountryFlag::setId(int value)
{
id = value;
}
Заполним класс данными:
CountryFlag flag1 = CountryFlag(1, "Russia", "russia.png");
CountryFlag flag2 = CountryFlag(2, "Belarus", "belarus.png");
Теперь, для того, чтобы проверить какие данные содержаться в полях экземпляра класса нам нужно написать что-то вроде этого:
qDebug() << flag1.getName(); qDebug() << flag1.getId();
и так далее, что неудобно и громоздко.
Выход – добавить специальный метод toString(), который выведет все необходимые значения в виде компактной строки.
Добавляем метод toString()
CountryFlag flag1 = CountryFlag(1, "Russia", "russia.png");
CountryFlag flag2 = CountryFlag(2, "Belarus", "belarus.png");
Добавим строку
qDebug() << flag1.toString();
Запустим – в консоли увидим:
"CountryFlag( id: 1, name: Russia, icon: russia.png )"
Все работает, как нужно. Но использование метода toString() слишком длинно, мы хотим использовать строку вида:
qDebug() << flag1;
Для этого нам придется перегрузить оператор <<
Перегрузка оператора <<
Для использования нашего класса с QDebug мы должны перегрузить оператор <<.
Обратите внимание, мы перегружаем его глобально!
В заголовочном файле класса добавим строку в конец файла, за закрывающей скобкой описания класса }; это важно!
QDebug operator<<(QDebug debug, const CountryFlag &flag);
Реализация
QDebug operator<<(QDebug debug, const CountryFlag &flag)
{
QDebugStateSaver saver(debug);
debug.nospace() << "CountryFlag( " << "id: " << QString::number(flag.getId()) << "," << " name: " << flag.getName() << "," << " icon: " << flag.getIcon() << " )";
return debug;
}
Пропишем
qDebug() << flag1;
Запустим:
CountryFlag( id: "1", name: "Russia", icon: "russia.png" )
Обратите внимание мы дублируем код из метода toString(), это вынужденная мера, в противном случае мы получим такую строку:
"CountryFlag( id: 1, name: Russia, icon: russia.png )"
Обратите внимание мы используем
const CountryFlag &flag
что означает что мы получаем константную ссылку на экземпляр класса CountryFlag, что в свою очередь гарантирует, что функция ничего не сможет изменить в полях класса CountryFlag.
Перегружаем << для указателя
Помимо простой переменной у нас может быть указатель на экземпляр класса, давайте добавим код:
CountryFlag *flag3 = new CountryFlag(1, "Russia", "russia.png"); qDebug() << flag3;
Запустим – результат неожиданный:
0x209a3c67bf0
Всё дело в том, что мы передаем указатель вместо константной ссылки, а следовательно qDebug() не использует перегруженный метод созданный нами.
Чтобы решить эту проблему, еще раз перегрузим оператор << на этот раз с указателем:
Заголовок:
QDebug operator<<(QDebug debug, const CountryFlag *flag);
Реализация
QDebug operator<<(QDebug debug, const CountryFlag *flag)
{
QDebugStateSaver saver(debug);
debug.nospace() << *flag;
return debug;
}
Запускаем – результат:
CountryFlag( id: "1", name: "Russia", icon: "russia.png" )
Здесь все просто мы разыменовываем ссылку и передаем ее QDebug, а он уже использует перегруженный оператор для вывода строки.
Заключение
Сегодня мы рассмотрели использование QDebug() для отладки классов в Qt5 с помощью перегруженного оператора <<.
Добавили метод toString() для вывода значения полей класса в виде строки.
Перегрузили оператор << для экземпляра класса CountryFlag.
Перегрузили оператор << указателя на экземпляра класса CountryFlag.
Добавить комментарий