Ich sehe, dass Q_NULLPTR
großzügig in Qt-Quellcode und Beispielen verwendet wird, aber ich habe keine Dokumentation gefunden, was genau es ist und wann es verwendet werden sollte.
Zum Beispiel in dieser offiziellen Demonstration des neuen Qt SerialBus-Moduls, die im neuen Qt v5.6 hinzugefügt wurde:
if (!m_canDevice->connectDevice()) {
delete m_canDevice;
m_canDevice = Q_NULLPTR;
Hat dies dem Zweck von nullptr
gedient, bevor es in C++ 11 hinzugefügt wurde? Wenn ja, sollte ich jetzt, da wir C++ 11 haben, Q_NULLPTR
verwenden?
PS: Ich habe versucht, den Qt-Quellcode nach der Definition des Makros zu durchsuchen, konnte ihn aber nicht finden.
Hat dies den Zweck von nullptr erfüllt, bevor es in C++ 11 hinzugefügt wurde? Wenn ja, sollte ich jetzt, da wir C++ 11 haben, Q_NULLPTR verwenden?
Ja (etwas) bzw. Nein.
C++ fehlte damals ziemlich, deshalb hatte Qt seine eigenen Sachen, die später überholt wurden, als C++ die Features einholte.
Abgesehen davon ist (war) Q_NULLPTR
funktional nicht mit nullptr
identisch, (wie Andrei feststellte, wird C++ 11 in nullptr
erweitert, wenn es unterstützt wird) gab es Ihnen keine Typensicherheit, nur die Syntax "sugar". Es illustrierte die Absicht für die Person, die den Code liest, und nicht für den Compiler wie nullptr
.
Q_NULLPTR
ist ein Makro, das als nullptr
ersetzt wird, wenn der Compiler c ++ 11 unterstützt, und als NULL
(das als 0
ersetzt wird), wenn dies nicht der Fall ist. Wenn Sie c ++ 11 verwenden, können Sie stattdessen nullptr
schreiben. Verwenden Sie NULL
, wenn Sie dies nicht tun.
Verwenden Sie Q_NULLPTR
, um vom Compiler unabhängig zu bleiben.
Wenn Sie sich jetzt für nullptr
entscheiden, wird Ihr Code nicht mit einem älteren C++ 98-Compiler kompiliert. Wenn Sie sich für NULL
entscheiden, verlieren Sie die Sicherheit des Typs c ++ 11, auch wenn diese in Ihrem aktuellen Compiler verfügbar ist.
Aus dem gleichen Grund existieren Makros wie qMove(x)
und der dazugehörige define Q_COMPILER_RVALUE_REFS
.
Tatsächlich hatte Q_NULLPTR
nur einen Zweck: Die Verwendung von nullptr
zuzulassen, ohne die Unterstützung für Compiler zu verlieren, die keine C++ 11/C++ 0x-Unterstützung hatten, da eine direkte Verwendung von nullptr
zu Fehlern in solchen Setups führen würde. Der Nachteil ist, dass der Fallback auf NULL
(oder 0
in älteren Qt-Versionen) mehrdeutig ist, was zu einem unbeabsichtigten Laufzeitverhalten führen und die unterstützten Anwendungsfälle im Vergleich zu nullptr
einschränken kann.
Verwenden Sie in dem seltenen Fall, dass Sie nicht C++ 11-kompatible Compiler zum Ziel haben, Q_NULLPTR
, stellen Sie jedoch sicher, dass der Code ordnungsgemäß funktioniert, wenn C++ 11-Funktionen deaktiviert sind. In allen anderen Situationen ist nullptr
die bessere Alternative, da es bei Verwendung mit älteren Compilern zu Kompilierungsfehlern anstelle eines fehlerhaften Laufzeitverhaltens kommt. Ab Qt 5.7 wurde die Unterstützung für die Kompilierung ohne C++ 11 eingestellt, sodass Q_NULLPTR
nicht erforderlich ist, wenn Sie von diesen Versionen abhängen.
Es gibt andere Funktionen wie qMove
oder Q_DECL_OVERRIDE
, die eine verbesserte Semantik ergeben, wenn sie zur Unterstützung von Compilern verwendet werden, ohne die Kompilierung bei älteren Compilern zu unterbrechen.