Pourquoi puis-je affecter un QObject * à un QObject?

Considérons le code suivant:

#include  class A : public QObject { Q_OBJECT public: A(QObject* parent = 0) : QObject(parent) {} } int main() { A a = new A(); return 0; } 

Pourquoi puis-je assigner un object de type A* à une variable de type A sans que le compilateur (ou le runtime) ne se plaint?

Dans ce code, le constructeur de A est utilisé pour convertir un A* en un object de type A , au lieu de l’ affecter . En général, le compilateur est autorisé à utiliser implicitement un constructeur correspondant en tant qu’opérateur de conversion. Le code suivant est donc le code légal:

 struct B { B(int i){} } int main() { B b = 5; return 0; } 

Dans le code de la question, le nom A* non nommé résultant de l’opérateur new est utilisé comme argument parent du constructeur de A Ceci est permis car A est dérivé de QObject (et correspond donc à la liste des arguments). Cependant, il s’agit clairement d’un comportement indésirable, car a n’est pas l’object renvoyé par new , mais un object de type A lié à cet object. (En outre, le new object ‘ed n’est jamais delete d, ce qui entraîne une fuite de mémoire.)

Pour éviter ce genre d’erreur subtile, il est généralement conseillé de rendre explicit le constructeur des classes QObject QObject afin d’empêcher le compilateur de l’utiliser de manière erronée en tant qu’opérateur de conversion. (Ceci s’applique également à des situations similaires, pas seulement à Qt.) Avec le code modifié suivant, le compilateur intercepte l’erreur:

 class A : public QObject { Q_OBJECT public: explicit A(QObject* parent = 0) : QObject(parent) {} }