web-dev-qa-db-ja.com

Q_NULLPTRをいつ使用するのですか?

Qtのソースコードと例でQ_NULLPTRが自由に使用されているのを確認しましたが、正確に何をいつ使用するかについてのドキュメントは見つかりませんでした。

たとえば、この公式では、新しいQtv5.6で追加された新しいQtSerialBusモジュールの デモンストレーション

if (!m_canDevice->connectDevice()) {
    delete m_canDevice;
    m_canDevice = Q_NULLPTR;

これは、C++ 11で追加される前に、nullptrの目的を果たしましたか?もしそうなら、C++ 11ができたので、Q_NULLPTRを使用する必要がありますか?

PS:マクロの定義についてQtソースコードを検索しようとしましたが、見つかりませんでした。

20
DBedrenko

これは、C++ 11で追加される前にnullptrの目的を果たしましたか?もしそうなら、C++ 11ができたので、Q_NULLPTRを使用する必要がありますか?

はい(やや)といいえ。

当時、C++はかなり不足していたため、Qtには独自のものがありましたが、C++が機能に追いついたため、後で廃止されました。

そうは言っても、Q_NULLPTRは機能的にはnullptrと同じではありません(Andreiが指摘したように、C++ 11がサポートされている場合はnullptrに拡張されます)、型の安全性は得られませんでした。構文「砂糖」だけ。これは、nullptrのようにコンパイラーではなく、コードを読む人に意図を示しています。

16
dtech

Q_NULLPTRはマクロであり、コンパイラがc ++ 11をサポートしている場合はnullptrとして置き換えられ、サポートしていない場合はNULL0として置き換えられます)として置き換えられます。 。 c ++ 11を使用する場合は、代わりにnullptrと書くことができます。そうでない場合は、NULLを使用してください。

20
Andrei R.

コンパイラに依存しないようにするには、_Q_NULLPTR_を使用します。

ここでnullptrを使用することにした場合、コードは古いc ++ 98コンパイラでコンパイルされません。 NULLを使用することにした場合、現在のコンパイラで使用可能であっても、c ++ 11型の安全性が失われます。

同じ理由で、qMove(x)のようなマクロと対応するdefine _Q_COMPILER_RVALUE_REFS_が存在します。

2
Martin Hennings

実際、Q_NULLPTRの目的は1つだけでした。nullptrを直接使用するために、C++ 11/C++ 0xをサポートしていないコンパイラのサポートを失うことなくnullptrを使用できるようにすることです。 var] _は、そのような設定でエラーが発生します。欠点は、NULL(または古いQtバージョンでは0)へのフォールバックにあいまいさがあり、意図しないランタイム動作が発生し、サポートされるユースケースがnullptrと比較して制限される可能性があることです。 。

C++ 11に準拠していないコンパイラを対象とするまれなケースでは、Q_NULLPTRを使用しますが、C++ 11機能が無効になっているときにコードが正常に機能することを確認してください。他のすべての状況では、レガシーコンパイラで使用するとバグのあるランタイム動作ではなくコンパイルエラーが発生するため、nullptrの方が適しています。 Qt 5.7以降では、C++ 11を使用しないコンパイルのサポートが終了したため、これらのバージョンに依存している場合はQ_NULLPTRは必要ありません。

qMoveQ_DECL_OVERRIDEのような他の機能があり、古いコンパイラでのコンパイルを中断することなく、サポートするコンパイラで使用するとセマンティクスが向上します。

1