このブログでは、C ++ 11標準の新機能であるnullptrについて説明し、その使用方法を説明します。
ポインターnull値nullptr
- C ++ 98のポインタnull値
通常、変数を宣言するときは、通常、変数に初期値を指定します。次に例を示します。
void TestPtr()
{
int* p1=NULL;
int* p2=0;
}
このNULLは、従来のCヘッダーファイル(stddef.h)では実際にはマクロです。
#ifndef NULL
#ifdef __cplusplus
#define NULL 0 //被定义为0
#else
#define NULL ((void *)0)//被定义为无类型指针(void*)的常量
#endif
#endif
ご覧のとおり、NULLはリテラル定数0として、または型指定されていないポインターの定数(void *)として定義できます。採用された定義に関係なく
、null値のポインターを使用すると、必然的にいくつかの問題が発生することは避けられません。といった:
void f(int)
{
cout << "f(int)" << endl;
}
void f(int*)
{
cout << "f(int*)" << endl;
}
int mian()
{
f(0);
f(NULL);
f((int*)NULL);
return 0;
}
操作の結果は次のとおりです。
私たちが思っていたものとは少し異なる結果になる可能性があり、これが問題です。f(0)が最初の関数を呼び出すことを知っておく必要がありますが、f(NULL)はポインターを渡すため、2番目の関数を呼び出すと思いますが、結果として、最初の関数はNULLのために呼び出されます。リテラル定数0。コンパイラはデフォルトでNULLを整数定数として扱います。これをポインタとして使用する場合は、強制的に(void *)0にする必要があるため、C ++ 11でnullptrが導入されています。
void f(int)
{
cout << "f(int)" << endl;
}
void f(int*)
{
cout << "f(int*)" << endl;
}
int mian()
{
f(nullpyr);
return 0;
}
この時、操作の結果は思った通りです
- nullptr与nullptr_t
互換性を考慮するために、C ++ 11は定数0のあいまいさを排除しません。C++ 11は、nullポインターを表すまったく新しいnullptrを提供します。C ++ 11がNULLに基づいて拡張されないのはなぜですか?これは、NULLが以前はマクロであり、コンパイラベンダーが異なればNULLの実装も異なり、NULLを直接拡張すると古いプログラムに影響を与える可能性があるためです。したがって、混乱を避けるために、C ++ 11はnullptrを提供します。つまり、nullptrはポインターのnull定数を表します。Nullptrには型があり、その型はnullptr_tであり、暗黙的にポインタ型に変換することしかできません。nullptr_tはヘッダーファイルで定義されています。
typedef decltype(nullptr) nullptr_t;
nullptrのタイプを直接見ると、より直感的になります。
int main()
{
cout << typeid(nullptr).name() << endl;
return 0;
}
nullptrのタイプは、標準ライブラリのヘッダーファイルにあるnullptr_tとして取得できます。
注意すべき3つのポイントがあります
。1。nullptrを使用してポインターのnull値を示す場合、nullptrはC ++ 11で新しいキーワードとして導入されたため、ヘッダーファイルをインクルードする必要はありません。
2. C ++ 11では、sizeof(nullptr)とsizeof((void *)0)は同じバイト数を占めます。
3.コードの堅牢性を向上させるために、ポインターnull値の後続の表現でnullptrを使用することをお勧めします。