-
含义与起源
- NULL:
- 在 C++ 中,
NULL
是一个宏定义,它在 C 头文件<stdio.h>
(在 C++ 中也可以通过<cstdio>
访问)等中被定义为((void*)0)
。它的主要目的是表示空指针,这个概念是从 C 语言继承而来的。在 C 语言中,void*
类型可以隐式转换为其他指针类型,所以NULL
可以用于给各种指针类型赋值,表示该指针不指向有效的内存地址。
- 在 C++ 中,
- nullptr:
nullptr
是 C++11 引入的一个关键字。它专门用于表示空指针。它的类型是std::nullptr_t
,这是一个新的类型,可以隐式转换为任何指针类型,但不能转换为非指针类型(除了bool
)。
- NULL:
-
类型安全方面的区别
- NULL:
- 由于
NULL
实际上是((void*)0)
,当在 C++ 中进行函数重载时,可能会导致一些类型不安全的问题。例如:
- 由于
- NULL:
#include <iostream>
void foo(int i) {
std::cout << "foo(int)" << std::endl;
}
void foo(char* p) {
std::cout << "foo(char*)" << std::endl;
}
int main() {
foo(NULL);
// 会调用foo(int),而不是预期的foo(char*),因为NULL是0,优先匹配整数类型的重载函数
return 0;
}
- nullptr:
nullptr
在类型安全方面有了改进。如果使用nullptr
来调用上述函数重载的例子,它会正确地选择foo(char*)
,因为nullptr
的类型std::nullptr_t
可以隐式转换为char*
类型,但不会错误地转换为int
类型。
#include <iostream>
void foo(int i) {
std::cout << "foo(int)" << std::endl;
}
void foo(char* p) {
std::cout << "foo(char*)" << std::endl;
}
int main() {
foo(nullptr);
// 正确调用foo(char*),因为nullptr可以隐式转换为char*类型
return 0;
}
- 兼容性方面
- NULL:
- 因为
NULL
从 C 语言继承而来,在旧的 C 和 C++ 代码中广泛使用。如果是维护旧代码或者在一些对 C 兼容性要求较高的场景下,NULL
仍然会被使用。不过,在新的 C++ 代码(C++11 及以后)中,为了更好的类型安全性,应该优先考虑使用nullptr
。
- 因为
- nullptr:
- 它是 C++11 新特性,在较新的 C++ 代码中更推荐使用。如果代码需要兼容旧的编译器(不支持 C++11),则不能使用
nullptr
,因为这些编译器无法识别这个关键字。
- 它是 C++11 新特性,在较新的 C++ 代码中更推荐使用。如果代码需要兼容旧的编译器(不支持 C++11),则不能使用
- NULL: