学习笔记:nullptr

C++中空指针的值是0。C++98, C++03, C++11, C++14, C++17... 永远也不会改变这个知识点。

例如: char* p=0;  //很直白,p没有指向任何地址。

但是0是个文字量,没有携带类型信息。

void foo(int);

void foo(char*);

foo(0); //根据直觉,好像应该调用foo(int),实际也是如此。

0和空指针的关系是:空指针的值是0;而0不一定是空指针(还可能是整数0)


C语言中,有一个很明确的空指针NULL。其定义为#define NULL ((void*)0)。在C语言里,NULL和0有着本质区别,NULL是有类型的(void*)!

C语言里,NULL和空指针的关系是:空指针的值是NULL,而NULL就是空指针。

foo(NULL);  //C语言角度看这句话,根据直觉,NULL是空指针,应调用void foo(char*);,实际也是如此。

foo(0);          //C语言角度看这句话,根据直觉,应调用void foo(int);,实际也是如此。


C++出现后,情况有了恶化。在C++语言中NULL被定义成0,而不是((void*)0)

因为 char* p = ((void*)0); 在C++中编译不过去,C++禁止void*隐式转换成其它指针,C++认为这是pitfall,是陷阱。不能为了一点小利而饮鸩止渴。

foo(NULL);  //C++语言角度看这句话,宏展开是foo(0),实际调用foo(int),完全不符合直觉,按照C语言习惯思考的程序员将可能遇到一个大BUG。


没有吃过亏人的,自然对NULL这个东西无所谓,吃过亏的人自然对NULL很不爽。因此要寻求完善,寻求改进。

虽然在字面上NULL能提示程序员们这是空指针,但是对计算机编译器,NULL与整数0没什么区别。编译器不知道NULL是空指针!!!!!


C++引入nullptr表示空指针,这是一个一等类的一个全局对象,占有存储空间,有自己的身份类型nullptr_t。

foo(nullptr);  //现在,调用foo(char*),直觉完全符合实际!!


nullptr有个神奇的功能,它能转换为任何类型的空指针。

char* p1 = nullptr;    //好像是执行这句  char* p1 = (char*)0;

std::vector* p2 = nullptr;    //好像是执行这句  std::vector* p2= (std::vector*)0;


其实只是用了简单的模板成员函数,利用了模板的一点小威力。

class nullptr_t
{
public:
    template<typename T> operator T*() const { return (T*)0; }
} ;

为什么不需要在使用nullptr时,引入对应的头文件呢?

显然C++编译器已经预置支持nullptr_t类型和null_ptr全局对象了。

相似的现象还有std::initializer_list,也是从语言层面引入的一个C++一等类型。






你可能感兴趣的:(学习笔记:nullptr)