Skip to content

Wiki

nullptr

About 8 min read

Existing English translations were reused. 1 current source blocks remain in Simplified Chinese, without triggering paid translation.

1.What problem does this section solve?

In traditional C/C++, use NULL or 0 to represent a null pointer. But this has a problem:

  • NULLActually, it is 0 (defined in C++ as #define NULL 0), which will be treated as an integer, causing a type mismatch.
  • In some overloaded functions, NULL may match the integer version of the function rather than the pointer version.

nullptr is a true "null pointer type" that resolves these type safety issues.

2.What is this feature?

nullptr is a keyword introduced in C++11, and its type is std::nullptr_t; it can be implicitly converted to a pointer of any type, but cannot be implicitly converted to an integer type. This allows the compiler to distinguish between a "null pointer" and the "integer 0".

3.C++ Standard Edition

C++11

4.Required header files

No additional header file is required.nullptr is a language keyword. To use the std::nullptr_t type, #include <cstddef> is required.

5.Basic syntax

int* p = nullptr;           // 空 int 指针
double* d = nullptr;        // 空 double 指针
std::shared_ptr<int> sp = nullptr;  // 空智能指针

// 判断空指针
if (p == nullptr) { ... }
if (!p) { ... }             // 等价写法
if (p) { ... }              // p 非空

6.Common Usage

Usage Description
int* p = nullptr; Initialize null pointer
p == nullptr Check if it is nullptr
if (ptr) Check if not null
func(nullptr) Pass null pointer argument
return nullptr; Return null pointer

7.Difference between nullptr and other "null"

nullptrIt only means "a pointer that does not point to any object." It is not the integer 0, nor an empty string, much less an empty container.

Express meaning Recommended usage Do not mix
Null pointer T* p = nullptr; Do not write NULL or 0
Null smart pointer std::shared_ptr<T> p = nullptr; Do not manually new/delete
Empty string std::string s; or "" Do not use nullptr
May have no return value std::optional<T> Do not force in a "special value"
Container is empty v.empty() Do not confuse with whether the pointer is null

8.Example code

8.1.Example 1: Basic usage of nullptr

#include <iostream>
#include <cstddef>

int main()
{
    int* p1 = nullptr;    // 空指针初始化
    int* p2 = 0;           // 旧写法(用 0 赋给指针)
    int* p3 = NULL;        // 旧写法(NULL 实际上还是 0)

    // 三种写法在简单的场景下等价
    std::cout << "p1 = " << p1 << "\n";
    std::cout << "p2 = " << p2 << "\n";
    std::cout << "p3 = " << p3 << "\n";

    // 判断空指针
    if (p1 == nullptr)
    {
        std::cout << "p1 is null\n";
    }

    return 0;
}

Running result:

p1 = 0
p2 = 0
p3 = 0
p1 is null

8.2.Example 2: Building on Example 1, nullptr resolves overload ambiguity

#include <iostream>

// 两个重载函数
void process(int n)
{
    std::cout << "process(int): " << n << "\n";
}

void process(int* p)
{
    if (p == nullptr)
    {
        std::cout << "process(int*): nullptr\n";
    }
    else
    {
        std::cout << "process(int*): " << *p << "\n";
    }
}

int main()
{
    process(42);        // 调用 process(int)
    process(nullptr);   // 调用 process(int*),明确是指针版本


    process(0);      // 调用 process(int)
    // process(NULL);   // ❌ 有歧义!编译器不知道调哪个

    int* p = nullptr;
    process(p);         // 调用 process(int*)

    return 0;
}

Running result:

process(int): 42
process(int*): nullptr
process(int): 0
process(int*): nullptr

8.3.Example 3: Building on Example 2, the application of nullptr in templates and smart pointers

#include <iostream>
#include <memory>

template <typename T>
void check_ptr(T* ptr)
{
    if (ptr == nullptr)
    {
        std::cout << "pointer is null\n";
    }
    else
    {
        std::cout << "pointer value = " << *ptr << "\n";
    }
}

int main()
{
    // 原始指针初始化为空
    int* rp = nullptr;
    check_ptr(rp);

    // 智能指针初始化为空
    std::shared_ptr<int> sp = nullptr;
    // 智能指针也可直接用 bool 判断
    if (!sp)
    {
        std::cout << "shared_ptr is null\n";
    }

    // 创建后赋值
    sp = std::make_shared<int>(100);
    if (sp)
    {
        std::cout << "shared_ptr value = " << *sp << "\n";
    }

    return 0;
}

Running result:

pointer is null
shared_ptr is null
shared_ptr value = 100

8.4.Example 4: nullptr is not magic—overloads with multiple pointers still require specifying the type

#include <iostream>

void reset(int* p)
{
    std::cout << "reset int pointer\n";
    if (p != nullptr)
    {
        *p = 0;
    }
}

void reset(double* p)
{
    std::cout << "reset double pointer\n";
    if (p != nullptr)
    {
        *p = 0.0;
    }
}

int main()
{
    int count = 42;
    double ratio = 3.14;

    reset(&count);   // 明确调用 int* 版本
    reset(&ratio);   // 明确调用 double* 版本

    int* count_ptr = nullptr;
    reset(count_ptr); // 仍然明确是 int* 版本

    // reset(nullptr); // ❌ 编译错误:nullptr 可以转成 int*,也可以转成 double*

    std::cout << "count = " << count << "\n";
    std::cout << "ratio = " << ratio << "\n";

    return 0;
}

Running result:

reset int pointer
reset double pointer
reset int pointer
count = 0
ratio = 0

9.Operation result

See the "run results" for each example above.

10.Key syntax explanation in the example

Example What it explains Newly introduced syntax Why it is written this way Notes
Example 1 Basic usage of nullptr nullptr、p == nullptr Initialize a pointer to "null", type-safe The type of nullptr is std::nullptr_t
Example 2 Resolving overload ambiguity In overloaded functions, nullptr matches the pointer version NULL cannot distinguish between integer and pointer overloads, but nullptr can This is the core reason nullptr replaces NULL
Example 3 Templates and smart pointers shared_ptr = nullptr、if(sp) Smart pointers can also be initialized with nullptr The bool conversion of a smart pointer is equivalent to != nullptr
Example 4 Multiple pointer overloads int*、double*、nullptr nullptr can exclude integer overloads, but it cannot choose a specific pointer type for you When there are multiple pointer overloads, first put nullptr into a pointer variable with an explicit type

11.Common Errors

Error 1: assuming that nullptr can match an arbitrary pointer overload

void f(int*);
void f(double*);

f(nullptr);  // ❌ 编译错误:两个指针版本都能匹配

Correct approach: first clarify the type:int* p = nullptr; f(p);

Error 2: Assigning nullptr to an integer

int n = nullptr;  // ❌ 编译错误!nullptr 不能隐式转换为整数

Correct approach: use 0 for integers and nullptr for pointers.

Error 3: Using NULL for pointer checks

if (p == NULL) { ... }  // 能工作,但不是最佳实践

Correct approach: use if (p == nullptr) or directly if (!p).

Error 4: Using nullptr as a Boolean value in an unexpected place

std::string s = nullptr;  // ❌ C++23 起直接禁止;旧标准中也是未定义行为

Correct approach: use std::string s; or std::string s = ""; for an empty string.

12.Usage Recommendations

  1. Always use nullptr instead of NULL or 0: this is the rule of modern C++, to avoid type ambiguity.
  2. Smart pointers can also use nullptr: such as std::shared_ptr<T> p = nullptr;.
  3. Use if (ptr) to check for non-null : equivalent to if (ptr != nullptr) but more concise.
  4. Do not assign nullptr to non-pointer types : integers, strings, etc. should not be initialized with nullptr.

13.Summary

  • nullptr 是类型安全的空指针常量,替代 NULL 和 0。
  • nullptr 的类型是 std::nullptr_t,只能隐式转为指针类型。
  • 在重载函数中,nullptr 可以正确匹配到指针版本,NULL 不行。
  • 现代 C++ 中永远使用 nullptr。