【C++】C++的nullptr和NULL
在 C++ 中,nullptr
和 NULL
都可以表示一个空指针(空地址),但它们的定义和用法存在显著差异。
1. NULL
是什么?
NULL
的定义:
在 C 和早期的 C++ 中,NULL
通常被定义为整数0
,其定义如下(来自标准库<cstddef>
或<stddef.h>
):#define NULL 0
- 行为:
NULL
是一个预处理器宏,用来表示一个整数常量0
。- 由于
NULL
被定义为0
,在某些上下文中可能会引发模糊性或类型问题。例如:void func(int); void func(void*); func(NULL); // 调用 func(int) 而不是 func(void*),因为 NULL 是 0(int 类型)。
2. nullptr
是什么?
-
nullptr
的定义:nullptr
是在 C++11 引入的新关键字,表示空指针常量,它是一个专用的指针类型。- 它的类型是
std::nullptr_t
,可以隐式转换为任何指针类型,但不能转换为整数类型。
-
行为:
nullptr
是一种明确的空指针类型,避免了NULL
带来的类型模糊问题。例如:void func(int); void func(void*); func(nullptr); // 明确调用 func(void*),因为 nullptr 是空指针类型。
3. 区别对比
特性 | NULL | nullptr |
---|---|---|
引入版本 | C 和早期的 C++ | C++11 |
定义 | 宏,通常定义为 #define NULL 0 | 关键字,类型为 std::nullptr_t |
类型 | 整数常量,通常是 int | 专用类型 std::nullptr_t |
指针转换 | 可隐式转换为指针类型,但可能引起歧义 | 可隐式转换为任何指针类型,无歧义 |
整数转换 | 是一个整数,参与整数运算 | 不是整数,不能参与整数运算 |
安全性 | 易引起类型混淆,存在潜在的歧义问题 | 类型安全,避免了指针和整数混淆的问题 |
适用性 | 向后兼容的代码,旧式 C++ 项目 | 现代 C++ 编程,推荐使用 |
4. **使用 **
-
推荐使用
nullptr
:nullptr
是类型安全的,不会与整数混淆。- 对于 C++11 及以上的代码,应始终使用
nullptr
,它是现代 C++ 编程的标准。
-
在旧代码中使用
NULL
:- 如果项目是混合 C 和 C++,或者使用了旧式代码,
NULL
可能仍然会被使用。 - 但在新开发中,应尽量避免使用
NULL
,改用nullptr
。
- 如果项目是混合 C 和 C++,或者使用了旧式代码,
5. **示例 **
展示了 nullptr
和 NULL
的不同效果:
#include <iostream>
using namespace std;
void func(int) {
cout << "func(int) called" << endl;
}
void func(void*) {
cout << "func(void*) called" << endl;
}
int main() {
func(NULL); // 输出:func(int) called,因为 NULL 是整数类型
func(nullptr); // 输出:func(void*) called,因为 nullptr 是空指针类型
// 类型检查
int* p1 = NULL; // 合法,NULL 转换为 int*
// int val = nullptr; // 错误,nullptr 不能隐式转换为 int
int* p2 = nullptr; // 合法,nullptr 是类型安全的空指针
return 0;
}