nullptr 到底是什么?

新手上路,请多包涵

我们现在拥有具有许多新功能的 C++11。一个有趣且令人困惑的(至少对我而言)是新的 nullptr

好吧,不再需要讨厌的宏 NULL

 int* x = nullptr;
myclass* obj = nullptr;

尽管如此,我还是不 nullptr 是如何工作的。例如, 维基百科文章 说:

C++11 通过引入一个新的 关键字 来作为一个可区分的空指针常量来纠正这个问题:nullptr。它的 类型为 nullptr_t ,可隐式转换并与任何指针类型或指向成员的指针类型相当。除了 bool 之外,它不能隐式转换或与整数类型相比较。

它如何是关键字和类型的实例?

另外,您是否还有另一个示例(除了维基百科),其中 nullptr 优于老旧的 0

原文由 Khaled Alshaya 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 714
2 个回答

它如何是关键字和类型的实例?

这并不奇怪。 truefalse 都是关键字,并且作为文字,它们具有类型( bool )。 nullptrstd::nullptr_t 类型的 _指针文字_,它是一个纯右值(你不能使用 & 它的地址)。

  • 4.10 关于指针转换说类型的prvalue std::nullptr_t 是一个空指针常量,并且一个整数空指针常量可以转换为 std::nullptr_t 。不允许相反的方向。这允许为指针和整数重载函数,并传递 nullptr 来选择指针版本。传递 NULL0 会混淆地选择 int 版本。

  • nullptr_t 转换为整数类型需要 reinterpret_cast ,并且与 (void*)0 转换为整数类型具有相同的语义(映射实现已定义)。 A reinterpret_cast 不能将 nullptr_t 转换为任何指针类型。如果可能,请依赖隐式转换或使用 static_cast

  • 该标准要求 sizeof(nullptr_t)sizeof(void*)

原文由 Johannes Schaub - litb 发布,翻译遵循 CC BY-SA 3.0 许可协议

根据 cppreferencenullptr 是一个关键字:

表示 指针文字。它是 std::nullptr_t 类型的纯右值。存在从 nullptr 到 任何指针类型 的空指针值和 任何指向成员类型 的指针的 _隐式转换_。任何空指针常量都存在类似的转换,包括 std::nullptr_t 以及宏 NULL 类型的值。

所以 nullptr 是不同类型的值 std::nullptr_t ,而不是 int 。它隐式转换为任何指针类型的空指针值。这个神奇的事情发生在你的幕后,你不必担心它的实现。 NULL 但是,它是一个宏,它是一个实现定义的空指针常量。它通常是这样定义的:

 #define NULL 0

即一个整数。

这是一个微妙但重要的区别,可以避免歧义。

例如:

 int i = NULL;     //OK
int i = nullptr;  //error
int* p = NULL;    //OK
int* p = nullptr; //OK

当你有两个这样的函数重载时:

 void func(int x);   //1)
void func(int* x);  //2)

func(NULL) 调用 1) 因为 NULL 是一个整数。 func(nullptr) 调用 2) 因为 nullptr 隐式转换为 int* 类型的指针。

此外,如果您看到这样的声明:

 auto result = findRecord( /* arguments */ );

if (result == nullptr)
{
 ...
}

并且您无法轻易找出 findRecord 返回的内容,您可以确定 result 必须是指针类型; nullptr 使这更具可读性。

在推断的上下文中,事情的工作方式略有不同。如果你有这样的模板函数:

 template<typename T>
void func(T *ptr)
{
    ...
}

你尝试用 nullptr 来调用它:

 func(nullptr);

你会得到一个编译器错误,因为 nullptrnullptr_t 类型。您必须将 nullptr 显式转换为特定的指针类型,或者使用 nullptr_tfunc 提供重载/特化。


使用 nulptr 的优点:

  • 避免函数重载之间的歧义
  • 使您能够进行模板专业化
  • 更安全、直观和富有表现力的代码,例如 if (ptr == nullptr) 而不是 if (ptr == 0)

原文由 jignatius 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题