浅谈 C++中的 NULL 和 nullptr
一、引入
在C语言中,我们经常使用 NULL 来表示空指针,但是在C++中,我们发现既有 nullptr,又有 NULL 。只看英文的话,好像都是空指针的意思。那么到底是怎么一回事呢?
二、C++对 NULL 的定义
在 C++98标准和 C++03标准中,还没有 nullptr ,只有 NULL 。那么在 C++中,NULL是如何定义的? 来看看编译器提供的头文件是怎么说的:
#ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif
通过上面的代码,我们发现在 C++中,NULL 被定义为整形常量 0(而在 C 中,NULL被定义为无类型指针常量 (void*) 0 )。
也就是说在 C++中,下面的这两行代码是完全等价的,没有区别。
int* p1 = NULL; int* p2 = 0;
三、C++中 NULL 的问题
其实 C++把 NULL 定义为 0 来表示空指针在大多数情形下不会有问题,因为 0 可以指地址编号为0的地址。
但是 NULL 作为参数在函数重载中的运行结果与我们的期望不符:
void test(int) { cout << "test(int)" << endl; } void test(int*) { cout << "test(int*)" << endl; } int main() { test(0); test(NULL); return 0; }
我们本以为 test(NULL) 会调用 test(int*) 这个函数,但实际上 test(NULL) 和 test(0) 调用的函数都是 test(int) 。
为什么会这样呢?
这是因为在 C++中,字面常量 0 既可以表示一个整形常量 0,也可以表示无类型指针常量 (void*) 0,但是编译器默认把它看成是一个整形常量 0 (如果把 0 当指针使用,就必须对其进行强转 (void*) 0 )。 由于 NULL 被定义为 0,编译器默认 NULL 就是整形常量 0,所以 test(NULL) 调用 test(int) 函数,而非 test(int*) 函数。
四、C++11标准的新增关键字 nullptr
为了解决这个问题,C++11标准增加了新的关键字 nullptr,保证在任何情况下都表示空指针。 让我们用上面的代码给 0 、NULL 和 nullptr 做个对比:
void test(int) { cout << "test(int)" << endl; } void test(int*) { cout << "test(int*)" << endl; } int main() { test(0); test(NULL); test(nullptr); return 0; }
因此,在 C++11标准出来以后,不推荐使用 NULL 来代表空指针。为了提高代码的健壮性,建议以后表示指针空值时最好都使用 nullptr 。
下一篇:
Java 字符串常用函数(简单直接易懂)