Last Updated: 2024-01-02 11:09:40 Tuesday
-- TOC --
在C语言中,用得好好的NULL
,C++为什么要搞出nullptr
呢?
NULL在C中,就是指向0地址void类型的空指针,定义为(void*)0
。而在C++中,被定义成了0,但我又觉得它似乎什么都不是,见下文!
在C++中编译下面这行代码会报错,但C代码不会:
// C++
int *p = (void*)0; // error
int *p = reinterpret_cast<int*>((void*)0); // compile ok, p == nullptr;
报错信息:
error: invalid conversion from ‘void*’ to ‘int*’ [-fpermissive]
这是C与C++的一个区别:C++不允许将void*隐式地转换成其它类型的指针。(必须使用C++中定义的named-conversion)
但C++还是重情义的,必须要考虑兼容C语言这个大兄弟,因此保留了NULL关键字,但重新将其定义为整数0,再增加nullptr类型来表达空指针(从C++11开始)。
因此,现在C++中定义空指针的方式如下:
int *k = NULL; // OK, but not recommended
int *j = 0; // the same with above, not recommended
int *h = nullptr; // BEST
还可以继续用NULL,为什么C++要搞出nullptr这个新的类型?
因为NULL被重新定义为整数0后,存在二义性,它既可以是空指针,也可以是整数,这会带来一些其它的问题。比如,下面是函数重载时出现的二义性:
#include <cstdio>
void abc(void*) {
printf("void*\n");
}
void abc(int) {
printf("int\n");
}
int main(void) {
abc(NULL);
return 0;
}
上面这段测试代码,在编译的时候,会有如下报错:
error: call of overloaded ‘abc(NULL)’ is ambiguous
如果NULL仅仅是整数0,那么编译器就不会ambiguous,因此NULL在C++中不仅仅是整数0....额...
需要将代码修改为使用nullptr:
abc(nullptr);
结论
在C中用NULL,在C++中只用nullptr表达空指针,如果要使用整数0,也不要用NULL,直接写0最好。
C++之父语录:
Should I use NULL or 0?
In C++ , the definition of NULL is 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem with NULL is that people sometimes mistakenly believe that it is different from 0 and/or not an integer. In pre-standard code, NULL was/is sometimes defined to something unsuitable and therefore had/has to be avoided. That's less common these days. If you have to name the null pointer, call it nullptr; that's what it's called in C++11. Then, "nullptr" will be a keyword.
为什么说NULL什么都不是呢?
NULL类型测试C++代码:
#include <iostream>
using namespace std;
int main(){
cout << is_same<decltype(NULL),decltype(0)>::value << endl;
cout << is_same<decltype(NULL),decltype((void*)0)>::value << endl;
cout << is_same<decltype(NULL),decltype(nullptr)>::value << endl;
return 0;
}
输出3个0!
因此,C++代码不要使用NULL!
本文链接:https://cs.pynote.net/sf/c/cpp/202209161/
-- EOF --
-- MORE --