Ответ 1
После часа игры с этим вопросом я понял, что model
является указателем на DataModel, а мой оператор <<
принимает только ссылки.
Я пытаюсь создать более полезные отладочные сообщения для моего класса, где хранятся данные. Мой код выглядит примерно так.
#include <QAbstractTableModel>
#include <QDebug>
/**
* Model for storing data.
*/
class DataModel : public QAbstractTableModel {
// for debugging purposes
friend QDebug operator<< (QDebug d, const DataModel &model);
//other stuff
};
/**
* Overloading operator for debugging purposes
*/
QDebug operator<< (QDebug d, const DataModel &model) {
d << "Hello world!";
return d;
}
Я ожидаю, что qDebug() << model
напечатает "Hello world!". Однако на выходе есть что-то вроде "QAbstractTableModel (0x1c7e520)".
Есть ли у вас какое-то представление о том, что случилось?
После часа игры с этим вопросом я понял, что model
является указателем на DataModel, а мой оператор <<
принимает только ссылки.
Я знаю это долгое время, но для того, чтобы быть документированным и помогать любым другим людям, которые в конечном итоге приходят сюда с такими же сомнениями, самый простой способ получить qDebug() < работа с вашим собственным типом печати, например, "Hello World" или что-то еще, заключается в том, чтобы реализовать неявное преобразование вашего класса в печатный тип, например QString (который хорошо поддерживается QDebug).
class Foo {
public:
Foo() { }
operator QString() const { return <put your QString here>; }
};
В вашем примере qDebug() печатает адрес вашей переменной, который является поведением по умолчанию для неизвестных типов.
На самом деле, по-видимому, вам нужно позаботиться о двух вещах:
Это даст вам:
QDebug operator<< (QDebug d, const DataModel &model) {
d << "Hello world!";
return d;
}
DataModel m;
qDebug() << "m" << m;
или
QDebug operator<< (QDebug d, const DataModel &model);
DataModel m;
qDebug() << "m" << m;
QDebug operator<< (QDebug d, const DataModel &model) {
d << "Hello world!";
return d;
}
Я тоже научился этому...
Я нашел этот ответ на форуме QT на raven-worx (предоставляя кредит, где кредит должен быть!)
В файле .h
:
QDebug operator<<(QDebug dbg, const MyType &type);
где MyType
- ваш класс, например DataModel
и type
- это экземпляр, который вы покажете.
И в файле .cpp
:
QDebug operator<<(QDebug dbg, const MyType &type)
{
dbg.nospace() << "MyType(" << .... << ")";
return dbg.maybeSpace();
}
и вы можете использовать QDebug space()
, nospace()
и другие методы для управления точным отображением потока.
Итак, для OP мы будем использовать:
// in the .h file:
class DataModel : public QAbstractTableModel {
// stuff
};
QDebug operator<<(QDebug dbg, const DataModel &data);
// in the .cpp file:
QDebug operator<<(QDebug dbg, const DataModel &data)
{
dbg.nospace() << "My data {" << data.someField << ',' << data.another << "}";
return dbg.maybeSpace();
}
// in some .cpp user of the class:
DataModel myData;
. . .
QDebug() << "The current value of myData is" << myData;
Вы внедрили только < оператора для справки. Если ваша переменная model
указатель, она будет использовать другую реализацию (а не вашу).
Чтобы использовать вашу реализацию, вы можете:
qDebug() << *model
Кстати, правильным способом реализации перегрузки QDebug operator<<(QDebug dbg, const T &data)
является использование класса QDebugStateSaver
:
QDebug operator<<(QDebug dbg, const QDataflowModelOutlet &outlet)
{
QDebugStateSaver stateSaver(dbg);
dbg.nospace() << ...;
return debug;
}
Таким образом, при выходе из функции будут корректно восстановлены настройки (то есть, чтобы вставить или не удалять промежутки между отпечатками).