Когда использовать Q_NULLPTR?
Я вижу, что Q_NULLPTR
используется либерально в исходном коде Qt и примерах, но я не нашел никакой документации о том, что именно и когда она должна использоваться.
Например, в этой официальной демонстрации нового модуля Qt SerialBus, добавленного в новый Qt v5.6:
if (!m_canDevice->connectDevice()) {
delete m_canDevice;
m_canDevice = Q_NULLPTR;
Это послужило цели nullptr
до того, что было добавлено в С++ 11? Если да, то теперь, когда у нас есть С++ 11, следует ли использовать Q_NULLPTR
?
PS: Я попытался найти исходный код Qt для определения макроса, но не смог его найти.
Ответы
Ответ 1
Это послужило цели nullptr до того, что было добавлено в C++ 11? Если да, то теперь, когда у нас есть C++ 11, следует ли использовать Q_NULLPTR?
Да (несколько) и Нет соответственно.
C++ не хватало еще в те дни, поэтому у Qt были свои вещи, которые позже стали устаревшими, поскольку C++ догнал функции.
При этом Q_NULLPTR
является (не) функционально таким же, как nullptr
(как заметил Андрей, если C++ 11 поддерживается, он расширяется до nullptr
), он не дает вам типа безопасности, просто синтаксис "сахар". Он проиллюстрировал намерение человека, читающего код, а не компилятору как nullptr
.
Ответ 2
Q_NULLPTR
- это макрос, который заменяется как nullptr
если компилятор поддерживает С++ 11 и как NULL
(который заменяется на 0
), если это не так. Если вы используете С++ 11, вместо этого вы можете написать nullptr
; используйте NULL
если вы этого не сделаете.
Ответ 3
Используйте Q_NULLPTR
чтобы оставаться независимым от компилятора.
Если теперь вы решите использовать nullptr
, ваш код не будет компилироваться с более старым компилятором С++ 98. Если вы решите использовать NULL
, вы потеряете безопасность типа С++ 11, даже если она доступна в вашем текущем компиляторе.
По той же причине существуют макросы, такие как qMove(x)
и соответствующее определение Q_COMPILER_RVALUE_REFS
.
Ответ 4
Фактически у Q_NULLPTR
была только одна цель: разрешить использование nullptr
без потери поддержки для компиляторов, у которых не было поддержки С++ 11/С++ 0x, поскольку прямое использование nullptr
приведет к ошибкам в таких настройках. Недостатком является то, что существуют двусмысленности его отказа от NULL
(или 0
в более старых версиях Qt), что может привести к непреднамеренному поведению в режиме исполнения и ограничить поддерживаемые варианты использования по сравнению с nullptr
.
В редком случае, когда вы нацеливаете компиляторы, отличные от С++ 11, используйте Q_NULLPTR
но убедитесь, что код работает хорошо, когда функции С++ 11 отключены. Во всех остальных ситуациях nullptr
является лучшей альтернативой, так как это приводит к ошибкам компиляции вместо ошибочного поведения во время выполнения при использовании с устаревшими компиляторами. Qt 5.7 и позже опустили поддержку для компиляции без С++ 11, поэтому нет необходимости в Q_NULLPTR
если вы Q_NULLPTR
от этих версий.
Существуют и другие функции, такие как qMove
или Q_DECL_OVERRIDE
которые дают улучшенную семантику при использовании для поддержки компиляторов без разбивки компиляции на старых компиляторах.