Рассмотрим следующий код:
#include <QObject>
class A : public QObject
{
Q_OBJECT
public:
A(QObject* parent = 0) : QObject(parent) {}
}
int main()
{
A a = new A();
return 0;
}
Почему я могу назначить объект типа A*
к переменной типа A
без жалоб на компилятор (или время выполнения)?
В этом коде конструктор A
используется для перерабатывать A*
к объекту типа A
, вместо назначение Это. В общем, компилятору разрешено неявно использовать соответствующий конструктор в качестве оператора преобразования, так что следующее является допустимым кодом:
struct B
{
B(int i){}
}
int main()
{
B b = 5;
return 0;
}
В коде вопроса безымянный A*
что вытекает из new
оператор используется в качестве parent
аргумент конструктора A
, Это разрешено с A
происходит от QObject
(и, следовательно, соответствует списку аргументов). Тем не менее, это явно нежелательное поведение, потому что a
не объект, возвращенный new
, но объект типа A
родом из этого объекта.
(В дополнение new
‘объект никогда не бывает delete
d, что приводит к утечке памяти.)
Чтобы избежать такого рода тонких ошибок, обычно рекомендуется сделать конструктор QObject
классы explicit
чтобы компилятор не использовал его как оператор преобразования. (Это относится и к подобным ситуациям, не только к Qt.)
Со следующим измененным кодом компилятор поймает ошибку:
class A : public QObject
{
Q_OBJECT
public:
explicit A(QObject* parent = 0) : QObject(parent) {}
}