Consider that we have create a custom type:
struct Point
{
Point(int x, int y):x(x),y(y){}
int x;
int y;
};
If we want to make it work with qDebug(), we need to implement a streaming operator:
QDebug operator<<(QDebug dbg, const Point &p)
But, wait ...
When we using pure c++, what we do is:
ostream &operator<<(ostream &out, const Point &p)
Why QDebug object is passed by value instead of reference?
qDebug() vs. std::cout
In first glance, qDebug() is very similiar to std::cout.
qDebug()<<"From Qt qDebug()";
std::cout<<"From C++ std::cout"<<std::endl;
However, each time we call qDebug(), a new QDebug
object will be created.
QDebug qDebug() { return QDebug(QtDebugMsg); }
while std::cout is a global std::ostream
object, the header file iostream is more or less like this:
namespace std
{
extern ostream cout;
static ios_base::Init __ioinit;
}
Why reference doesn't work for QDebug
We know that,
qDebug() << Point(1,2);
can be wrriten as:
QDebug(QtDebugMsg) << Point(1,2);
Which can also be wrriten as:
operator <<(QDebug(QtDebugMsg), Point(1,2));
As we can see, a temporary QDebug object is passed to the function in above statements.
But in C++, we know that,
A temporary cannot be bound to a non-const reference.
That why
QDebug operator<<(QDebug dbg, const Point &p)
should be used instead of
QDebug & operator<<(QDebug &dbg, const Point &p)
Problem?
Some one complain that, though
QDebug & operator<<(QDebug &dbg, const Point &p)
doesn't work for qDebug()<<Point(1,2);
, but it indeed works for qDebug()<<""<<Point(1,2);
. Why?
The latter statement can be re-written as
operator <<(QDebug(QtDebugMsg).operator <<(""), Point(1,2));
and note that, QDebug has provided the member function for type char *
:
QDebug & QDebug::operator<<(const char * s);
in which a reference to current QDebug object is return.
So C++ compiler will be happy with this now.