问题
Consider the following code:
#include <QObject>
class A : public QObject
{
Q_OBJECT
public:
A(QObject* parent = 0) : QObject(parent) {}
}
int main()
{
A a = new A();
return 0;
}
Why can I assign an object of type A*
to a variable of type A
without the compiler (or runtime) complaining?
回答1:
In this code, the constructor of A
is used to convert an A*
to an object of type A
, instead of assigning it. In general the compiler is allowed to implicitly use a matching constructor as a conversion operator, so that the following is legal code:
struct B
{
B(int i){}
}
int main()
{
B b = 5;
return 0;
}
In the code of the question, the unnamed A*
that results from the new
operator is used as the parent
argument of the constructor of A
. This is allowed since A
is derived from QObject
(and thus matches the argument list). However, this is clearly undesired behaviour because a
is not the object returned by new
, but an object of type A
parented to that object.
(In addition, the new
'ed object is never delete
d, resulting in a memory leak.)
To prevent this kind of subtle error, it is generally advised to make the constructor of QObject
-derived classes explicit
to prevent the compiler from mis-using it as a conversion operator. (This applies to similar situations too, not only to Qt.)
With the following modified code, the compiler will catch the error:
class A : public QObject
{
Q_OBJECT
public:
explicit A(QObject* parent = 0) : QObject(parent) {}
}
来源:https://stackoverflow.com/questions/30322423/why-can-i-assign-a-qobject-to-a-qobject