nullptr是什么?

7 浏览
0 Comments

nullptr是什么?

我们现在有了很多新功能的C++11版本。一种有趣而令人困惑的新特性(至少对我而言)是新的nullptr

现在不需要那个讨厌的NULL宏了。

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

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

C++11通过引入一个新的关键字来作为突出的空指针常量:nullptr。它是<强>nullptr_t类型,可以隐式地转换和比较任何指针类型或成员指针类型。除了bool之外,它不可隐式转换或比较整数类型。

它是如何成为关键字和一个类型的实例?

此外,你有另一个例子(除了维基百科上的)证明nullptr优于旧的0吗?

admin 更改状态以发布 2023年5月20日
0
0 Comments

为什么C++11中需要nullptr?它是什么?为什么NULL不足够?

C++专家Alex Allain在这里表述得很好(以下为我加粗的重点):

...想象一下你有以下两个函数声明:

void func(int n); 
void func(char *s);
func( NULL ); // guess which function gets called?

虽然看起来第二个函数将被调用——你毕竟是传递了一个看似指针的参数,但实际上会调用第一个函数!问题在于,因为NULL是0,而0是一个整数,所以在这种情况下会调用第一版的func函数。虽然这种情况不是经常发生,但当发生时,是非常令人沮丧和困惑的。如果你不知道正在发生的细节,它可能看起来像编译器的bug。一个看起来像编译器bug的语言特性,显然不是你想要的。

这便引入了nullptr。在C++11中,nullptr是一个新的关键字,应该(而且应该!)用于代替NULL指针;换句话说,在以前使用NULL的任何地方,你现在应该使用nullptr。 它对你这个程序员来说并不更清楚(每个人都知道NULL的含义),但它对编译器更明确,编译器不再看到0被用于具有特殊含义的指针。

Allain在他的文章中写道:

不管怎样——对于C++11的一般规则是,只要以前会使用NULL,现在就应该开始使用nullptr

(以下为我的话):

最后,不要忘记nullptr是一个对象——一个类。它可以用于以前使用NULL的任何地方,但如果你因某种原因需要它的类型,它的类型可以使用decltype(nullptr)来提取,或者直接用std::nullptr_t描述,它只是decltype(nullptr)typedef,如下所示:

头文件中定义:

参见:

  1. https://en.cppreference.com/w/cpp/types/nullptr_t
  2. https://en.cppreference.com/w/cpp/header/cstddef

namespace std
{
typedef decltype(nullptr) nullptr_t; // (since C++11)
// OR (same thing, but using the C++ keyword `using` instead of the C and C++ 
// keyword `typedef`):
using nullptr_t = decltype(nullptr); // (since C++11)
} // namespace std

参考资料:

  1. Cprogramming.com: Better types in C++11 - nullptr, enum classes (strongly typed enumerations) and cstdint
  2. https://en.cppreference.com/w/cpp/language/decltype
  3. https://en.cppreference.com/w/cpp/types/nullptr_t
  4. https://en.cppreference.com/w/cpp/header/cstddef
  5. https://en.cppreference.com/w/cpp/keyword/using
  6. https://en.cppreference.com/w/cpp/keyword/typedef
0
0 Comments

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

这并不令人惊讶。 truefalse 都是关键字,并且作为文字它们具有类型(bool)。 nullptr 是类型为 std::nullptr_t 的指针文字,它是 prvalue 类型(无法使用 & 采取它的地址)。

  • 关于指针转换的 4.10 规则说明,std::nullptr_t 类型的 prvalue 是空指针常量,并且可以将整数空指针常量转换为 std::nullptr_t。反向转换是不允许的。这允许为指针和整数重载函数,并通过传递 nullptr 选择指针版本。传递 NULL0 会令人困惑地选择 int 版本。

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

  • 标准要求 sizeof(nullptr_t) 等于 sizeof(void*)

0