Является ли qApp-›exec() действительным при использовании QApplication

Допустимо ли вызывать qApp->exec() или QCoreApplication::exec(), если я использую экземпляр QApplication? Поскольку это статическая функция, в обоих случаях будет вызываться QCoreApplication::exec(). Однако оказывается, что даже если я вызываю одну из них, моя программа на основе QApplication работает нормально - это просто удача/совпадение или это действительно так?

Спасибо за вашу помощь!


person Felix    schedule 24.10.2015    source источник


Ответы (3)


Короткий ответ:

Это не удача, так как статические функции должны вести себя также как обычные невиртуальные функции.

Длинный ответ:

Статическая функция — это функция-член, которая не использует указатель this. Когда вы вызываете его из объекта, он ведет себя как обычный член.

Поскольку QApplication является производным от QCoreApplication, а exec() является членом QCoreApplication, он также является членом объектов типов, производных от QCoreApplication.

qApp возвращает указатель на объект QApplication, который также является QCoreApplication, поэтому он также содержит exec().

person Dragos Pop    schedule 24.10.2015
comment
qApp не является функцией, поэтому вы не можете называть ее как таковую (т. е. qApp() является ошибкой). Объект, который дает вам qApp, является объектом QCoreApplication, а не объектом QApplication. - person Craig Scott; 25.10.2015
comment
Вы правы, это всего лишь макрос, и использование () является ошибкой. Тем не менее, в зависимости от типа приложения, он приводится к реальному типу экземпляра. Например, если вы включите QWidgets, он будет преобразован в QApplication. - person Dragos Pop; 25.10.2015
comment
Ой. Итак, что означает qApp, зависит от того, какие заголовки вы включаете. :( - person Craig Scott; 25.10.2015
comment
Спасибо! Теперь я понимаю. Я почему-то думал, что у QApplication есть своя функция QApplication::exec, но это не так! Это проясняет. @Craig Scott: Нет, qApp всегда указывает на QCoreApplication::instance() - person Felix; 25.10.2015

qApp — это просто #define до QCoreApplication::instance(). Все, что qApp делает в вашем использовании, сообщает компилятору, где найти функцию exec(). Но поскольку exec() является статической функцией, она не вызывается через объект, даже если ваш код делает ее похожей на таковую. Таким образом, qApp->exec() должно быть полностью эквивалентно QCoreApplication::exec() с точки зрения компилятора. Тем не менее, я не знаю, требует ли стандарт C++, чтобы qApp было ненулевым в этом случае, хотя технически это не нужно использовать.

person Craig Scott    schedule 24.10.2015
comment
Чтобы было ясно, как упомянул @dragos-pop, QApplication является просто подклассом QCoreApplication. В исходном вопросе не имеет значения, создает ли ваше приложение объект QCoreApplication или объект QApplication, вы все равно можете вызывать exec() таким же образом. - person Craig Scott; 25.10.2015

QT использует одноэлементный шаблон в QApplication, поэтому все ваши вызовы заканчиваются вызовом одного экземпляра QApplication. Странно, почему они решили использовать qApp для поездки, но кажется, что это самая короткая строка для ввода. Я предпочитаю сохранить указатель на исходное приложение QApplication, которое вы создали сами.

person Christopher Oezbek    schedule 24.10.2015
comment
Я считаю, что qApp — это историческое похмелье с самых первых дней существования Qt. Возможно, он начал свою жизнь как настоящая глобальная переменная, но, как упоминается в моем ответе, теперь это просто #define для QCoreApplication::instance(). Предположительно, он был сохранен, чтобы старый код мог продолжать работать с минимальными изменениями кода, когда люди обновляются до более новых версий Qt. - person Craig Scott; 25.10.2015