152
121

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

NULL と nullptr って何が違う?

Posted at

C++11 では、NULL に代わるものとして nullptr キーワードが追加されています。

この話を聞くと「NULL じゃだめなの?」と一度は思う人は少なく無いと思います。
そこで、今回は NULL と nullptr の違いについて書いてみたいと思います。

NULL じゃ出来ないことがある

今更言うことでもないですが、NULL は以下のようにマクロで定義されています。

#define NULL    0

マクロということは、NULL なんて大層な扱いになっていても 0 以外の何者でもないということです。

そこで、以下のコードと実行結果を見てみます。

test.cpp
#include <iostream>

using namespace std;

void Func(void * p) {
    cout << __FUNCSIG__ << endl;
}
void Func(int v) {
    cout << __FUNCSIG__ << endl;
}
int main()
{
    Func(10);
    Func(NULL);

    return 0;
}
output
void __cdecl Func(int)
void __cdecl Func(int)

NULL を指定しても Func(void * v) ではなく、Func(int v) が呼び出されてます。
そりゃそうですよね。

コンパイラから見たら NULL はポインタではなく、ただの 0 なんですから。

もし、Func(void * v) を呼びたいのであれば

Func((void*)NULL);

のように明示的にキャストしてやる必要があります。

が、NULL ポインタを明示的にキャストするのはなんともおかしな話ですし、
何より「それくらい勝手にやってくれよ!」って思いますよね。

#nullptr だからこそできる事がある
C++11 で追加された nullptr キーワードは、まさしくそのために用意されたものです。

以下が NULL を nullptr に置き換えたコードと実行結果です。

test2.cpp
#include <iostream>

using namespace std;

void Func(void * p) {
    cout << __FUNCSIG__ << endl;
}
void Func(int v) {
    cout << __FUNCSIG__ << endl;
}
int main()
{
    Func(10);
    Func(nullptr);

    return 0;
}
output
void __cdecl Func(int)
void __cdecl Func(void *)

nullptr を指定したら、見事に Func(void *) が呼び出されています。

このように、nullptr を指定すると、きちんとポインタとして扱ってくれます。

nullptr は nullptr_t 型

また、nullptr はポインタとして扱われますが、 型としては std::nullptr_t 型 という扱いになっています。

どういう事かというと、それは以下のコードと実行結果を見てもらえればわかるかと思います。

test3.cpp
#include <iostream>

using namespace std;

void Func(void * p) {
    cout << __FUNCSIG__ << endl;
}

void Func(int v) {
    cout << __FUNCSIG__ << endl;
}

void Func(nullptr_t p) {
    cout << __FUNCSIG__ << endl;
}

int main()
{
    Func(10);
    Func(nullptr);

    return 0;
}
output
void __cdecl Func(int)
void __cdecl Func(nullptr)

このように、ポインタを引数として取る関数と nullptr_t を引数として取る関数がオーバーロードされている場合は、
nullptr の本来の型である nullptr_t が優先して呼び出されることになります。

152
121
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
152
121

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?