这是一篇关于关于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修饰