这是一篇关于关于NULL和nullptr使用的问题,在c++11之前,初始化指针主要使用NULL关键字表示一个空指针

1.C语言中初始化指针

C语言中初始化指针使用NULL初始化,本质上在C语言中NULL被定义为一个宏,值为((void*)0)。在mingW编译器中有如下代码

#ifndef NULL
#ifdef __cplusplus
#ifndef _WIN64
#define NULL 0
#else
#define NULL 0LL
#endif  /* W64 */
#else
#define NULL ((void *)0)
#endif
#endif
/**************************************************
<1>如果未定义NULL,且定义了__cplusplus,如果是32位系统,则#define NULL 0LL
<2>如果未定义NULL,且定义了__cplusplus,如果是64位系统,则#define NULL 0
<3>如果未定义NULL,且未定义__cplusplus,直接定义#define NULL ((void *)0)
***************************************************/

- [ ] ((void)*)0的含义:不结合上下文,单独看该句,意思为一个无类型的指向0地址的指针,由于无类型因此不能确定访问内存块的长度

- [ ] void 指针是否可直接使用? 在一般情况下,需要强转为有类型指针后才可使用,类型决定了可访问内存的长度,参考malloc返回void

2.c++中为什么引入nullptr

  • C++ 不允许void 隐式转换成其它指针类型,因此NULL在c++中只能是0,如果是类C的(void)0的话导致编译不过
  • 0只是一个魔术,并没有实际意义
  • NULL在c++中本身为一个int类型(0),这在模板自动类型推导时,会被推导为int *类型,而nullptr就可以被推导为T *
  • NULL在c++静多态中,函数调用在编译期会产生问题

3.nullptr的简单实现

nullptr的简单实现有如下代码

#include <iostream>
using namespace std;
const class mynullptr_t
{
public:
    template<class T>
    inline operator T*() const
    {
        cout << "T* is called" << endl;
        return 0;
    }
    template<class C, class T>
    inline operator T C::*() const
    {
        cout << "T C::* is called" << endl;
        return 0;
    }
    void operator&() = delete;
#if 0
private:
    void operator&() const;
#endif 

} mynullptr = {};

class A{
public:
      int *a;
};

int main(){

    int *p = mynullptr;
    int A::*a = mynullptr;
    cout << p << endl;
    cout << a << endl;

}

- [ ] 上述代码可见,不能对nullptr进行取址操作,被重载的运算符是私有的,有些代码中也被delet修饰