字面常量0的类型是int
而非指针,当C++
在只能使用指针的语境中发现一个0,它也会把它勉强解释为空指针。C++的基本观点还是0的类型为int
,而非指针;从实际效果来说,以上结论对于NULL
也成立(标准允许各个实现给予NULL
非int
的整数类型(如long))。
C++98
中,这样的基本观点可能在指针和整形之间i进行重载时可能会发生意外。
void f(int);
void f(bool);
void f(void *);
f(0); // 调用f(in)
f(NULL);// 可能会通不过编译,但一般会调用f(int)
f(NULL)
的不确定性是NULL
的类型在实现中的余地的一种反映。比如,假设NULL
的定义为0L
,那么f(NULL)
调用就有多意性了。因为从long
到int
,从long
到bool
,还有从0L
到void *
的类型转换被视为同样好的。指导原则是不要在指针类型和整型之间做重载
nullptr
的优点在于、它不具备整型类型。也不具备指针类型,但你可以把它想成一种任意类型的指针;
调用重载函数f
时传入nullptr
会调用void*
那个重载版本,因为nullptr
无法视作任何一种类型
f(nullptr); //调用的是f(void*)这个重载版本
使用nullptr
而非0
和NULL
就避免了重载决议中的意外,也提升了代码的清晰性,尤其在在涉及auto
变量时:
auto result = finRecord(/*实参*/)
if (result == 0) {
//...
}
如果你刚好不知道findeRecord
的返回值类型的话,那么result
是指针类型还是整数类型就不清楚了;但是如果你看到的是下面这段代码:
auto result = finRecord(/*实参*/)
if (result == nullptr) {
//...
}
这里没有多义性了:result
必然具备指针类型