问题
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 deleted, 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