C++中的NULL和nullptr
NULL
和 nullptr
都是用于表示空指针的常量,但它们在 C++ 中有一些重要的区别,特别是随着 C++11 引入了 nullptr
之后,nullptr
成为了更推荐的选择。以下是两者的主要区别:
1. 类型
-
NULL
:在 C 和 C++ 中,NULL
是一个宏,通常定义为0
(或(void*)0
),它本质上是整数常量。由于它是一个整数常量,编译器在使用时可能无法区分空指针和零值的整数,因此可能会引起一些类型转换的问题。#define NULL 0
NULL
可以隐式转换为任何指针类型(因为 0 可以被视为空指针)。- 由于其是整数常量,有时可能会导致不明确的转换。
-
nullptr
:nullptr
是 C++11 中引入的一个关键字,专门用于表示空指针。它是一个类型安全的指针常量,具有明确的指针类型 (std::nullptr_t
),并且不能隐式转换为整数类型。nullptr_t
nullptr
具有明确的类型std::nullptr_t
,并且只能用于指针类型。- 编译器能够识别
nullptr
并明确区分它与其他类型(如整数或枚举)。
2. 类型安全
-
NULL
:由于NULL
是一个宏,它通常等于0
,并且0
是一个整数常量,所以NULL
可以隐式转换为整数类型(这可能导致不明确的类型转换)。int* p = NULL; // 可以通过隐式转换 int i = NULL; // 允许将空指针赋值给整数
-
nullptr
:nullptr
是类型安全的,它只能与指针类型匹配,并且不会进行隐式转换。这消除了由于将NULL
用于整数类型而引起的潜在问题。int* p = nullptr; // 正确 int i = nullptr; // 错误:不能将 nullptr 赋值给整数类型
这样,
nullptr
提供了更强的类型检查和防止误用。
3. 用于函数重载
由于 nullptr
具有明确的类型(std::nullptr_t
),它可以帮助解决函数重载时的歧义问题,而 NULL
由于被定义为 0
,可能导致不同类型重载之间的冲突。
例如,如果你有两个重载函数,一个接受指针,另一个接受整数类型,使用 NULL
可能会导致二义性:
void func(int) {
std::cout << "Integer version\n";
}
void func(char*) {
std::cout << "Pointer version\n";
}
int main() {
func(NULL); // 可能引起二义性:NULL 被视为 0,既可以是 int 类型也可以是指针类型
}
使用 nullptr
可以消除这种二义性,因为它明确表示为空指针:
int main() {
func(nullptr); // 明确调用指针版本
}
4. 容易出错的情况
-
NULL
:如果在某些情况下将NULL
用作整数或其他类型时,可能会导致逻辑错误或难以发现的 bug。if (some_pointer == NULL) { // 检查空指针时没有问题 // do something } if (some_pointer == 0) { // 0 和 NULL 相同,但 0 可能被错误地用作整数 // do something }
-
nullptr
:nullptr
不能与整数或其他类型隐式转换,因此不容易出错。if (some_pointer == nullptr) { // 更安全,更明确 // do something }
总结
特性 | NULL | nullptr |
---|---|---|
类型 | 宏,通常等于 0 (整数常量) |
关键字,类型为 std::nullptr_t |
类型安全 | 不安全,可能会隐式转换为整数类型 | 类型安全,不能隐式转换 |
使用范围 | 可用于指针和整数类型 | 仅用于指针类型 |
函数重载 | 可能导致重载歧义 | 消除重载歧义 |
C++标准 | 在 C 和 C++ 中都可以使用 | 从 C++11 引入 |
推荐使用 nullptr
- 在 C++ 中,推荐使用
nullptr
代替NULL
,因为它更类型安全,避免了由于隐式转换引起的潜在问题,并且更清晰地表达了代码意图。
本文来自博客园,作者:海_纳百川,转载请注明原文链接:https://www.cnblogs.com/chentiao/p/18571155,如有侵权联系删除