Почему я могу назначить QObject * на QObject?

Рассмотрим следующий код:

#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 без жалоб на компилятор (или время выполнения)?

3

Решение

В этом коде конструктор 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‘объект никогда не бывает deleted, что приводит к утечке памяти.)

Чтобы избежать такого рода тонких ошибок, обычно рекомендуется сделать конструктор QObjectклассы explicit чтобы компилятор не использовал его как оператор преобразования. (Это относится и к подобным ситуациям, не только к Qt.)
Со следующим измененным кодом компилятор поймает ошибку:

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

Другие решения


По вопросам рекламы [email protected]