NULL 和 nullptr 是否都指向相同的地址或 NULL 指向任何地方? (我在很多地方看到nullptr指向零地址)
Does both NULL and nullptr point to same address or NULL points to nowhere? (I have seen in many places that nullptr points to zero address)
NULL和nullptr是指向同一个地址还是NULL指向任何地方?
(我在很多地方看到nullptr指向内存不可访问的零地址)
NULL
只是 0
的预处理器常量。因为地址是一个数字,所以地址 0
是为 'bad' 地址保留的。但是没有什么可以阻止您将 NULL
分配给任何数字变量,因为它将被替换为 0
。 nullptr
是一个特殊常量,它只适用于指针。但它本质上是 0
.
的指针常量
澄清一些术语可能会有用。一个指针 指向 一个对象。指针的值是一个地址值。 不指向对象的指针有一个特殊的地址值。我们称这样的指针为“空指针”。当您将 NULL
或 nullptr
值分配给指针时,它会变成空指针。
由于所有空指针比较相等,static_cast<void*>(NULL) == static_cast<void>(nullptr)
.
首先,nullptr
是C++09的补充(好吧,它包含在C++0x中,C++0x当时将在某个地方发布,最终成为C++11)。所以在此之前,没有 nullptr
,只有 NULL
。
重点是使空值明确无误。无法保证 NULL
是 0
。例如,它可能是 0L
。也可以是42
。将它传递给重载函数可能会导致意外行为。为了避免这种歧义,引入了新的强类型 nullptr
,现在您可以精确地创建重载甚至模板来处理这种情况。现在你可以重载你的构造函数了。
http://coliru.stacked-crooked.com/a/7faac5903a02e365
#include <iostream>
void func(int* ptr)
{
std::cout << "ptr" << std::endl;
}
void func(size_t size)
{
std::cout << "size" << std::endl;
}
void func(std::nullptr_t)
{
std::cout << "nullptr" << std::endl;
}
int main()
{
int myValue(10);
func(myValue);
func(&myValue);
func(nullptr);
// Good luck with this
// func(NULL);
}
这里准确地说,NULL
是常量文字,可以隐式转换为任何指针,并且有null pointer value
。这同样适用于 nullptr
,因此在这两种情况下,您都可以保证它们将生成带有 null pointer value
的指针。这并不意味着它是 0
并且从技术上讲它甚至不能保证它会是相同的值,至少我没有找到必须只有一个 null pointer value
的证据。显然,实现其中一个以上是荒谬的,但如果未指定,则无法保证。在任何现代实现中,从 NULL
和 nullptr
创建的指针将指向相同的 null pointer value
地址,编译器将其与任何其他可能有效的地址区别对待。
最重要的是,nullptr 没有值。它不能转换为任何数字,它只能转换为任何指针类型。您不能说 nullptr
为零,因为它不是。它 将 转换为任何指针类型,然后将其转换为数值 null pointer value
无论它在给定的 platform/compiler.
上是什么
NULL和nullptr是指向同一个地址还是NULL指向任何地方? (我在很多地方看到nullptr指向内存不可访问的零地址)
NULL
只是 0
的预处理器常量。因为地址是一个数字,所以地址 0
是为 'bad' 地址保留的。但是没有什么可以阻止您将 NULL
分配给任何数字变量,因为它将被替换为 0
。 nullptr
是一个特殊常量,它只适用于指针。但它本质上是 0
.
澄清一些术语可能会有用。一个指针 指向 一个对象。指针的值是一个地址值。 不指向对象的指针有一个特殊的地址值。我们称这样的指针为“空指针”。当您将 NULL
或 nullptr
值分配给指针时,它会变成空指针。
由于所有空指针比较相等,static_cast<void*>(NULL) == static_cast<void>(nullptr)
.
首先,nullptr
是C++09的补充(好吧,它包含在C++0x中,C++0x当时将在某个地方发布,最终成为C++11)。所以在此之前,没有 nullptr
,只有 NULL
。
重点是使空值明确无误。无法保证 NULL
是 0
。例如,它可能是 0L
。也可以是42
。将它传递给重载函数可能会导致意外行为。为了避免这种歧义,引入了新的强类型 nullptr
,现在您可以精确地创建重载甚至模板来处理这种情况。现在你可以重载你的构造函数了。
http://coliru.stacked-crooked.com/a/7faac5903a02e365
#include <iostream>
void func(int* ptr)
{
std::cout << "ptr" << std::endl;
}
void func(size_t size)
{
std::cout << "size" << std::endl;
}
void func(std::nullptr_t)
{
std::cout << "nullptr" << std::endl;
}
int main()
{
int myValue(10);
func(myValue);
func(&myValue);
func(nullptr);
// Good luck with this
// func(NULL);
}
这里准确地说,NULL
是常量文字,可以隐式转换为任何指针,并且有null pointer value
。这同样适用于 nullptr
,因此在这两种情况下,您都可以保证它们将生成带有 null pointer value
的指针。这并不意味着它是 0
并且从技术上讲它甚至不能保证它会是相同的值,至少我没有找到必须只有一个 null pointer value
的证据。显然,实现其中一个以上是荒谬的,但如果未指定,则无法保证。在任何现代实现中,从 NULL
和 nullptr
创建的指针将指向相同的 null pointer value
地址,编译器将其与任何其他可能有效的地址区别对待。
最重要的是,nullptr 没有值。它不能转换为任何数字,它只能转换为任何指针类型。您不能说 nullptr
为零,因为它不是。它 将 转换为任何指针类型,然后将其转换为数值 null pointer value
无论它在给定的 platform/compiler.