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