nullptr
nullptr一、nullptr 基础概念1.1 为什么需要 nullptr在 C11 之前NULL被定义为0会导致了两个主要问题类型不安全性0既可以是整数也可以是空指针函数重载二义性无法区分int和指针类型的重载// C 中 NULL 的本质#ifdef__cplusplus#defineNULL0// CNULL 就是 0#else#defineNULL((void*)0)// CNULL 是 void* 类型#endif1.2 nullptr 的特性特性说明类型安全nullptr有独立的类型std::nullptr_t可隐式转换可转换为任何指针类型不能转换为整数不能赋值给int等整数类型常量性是常量不能修改大小sizeof(nullptr)sizeof(void*)二、C 与 C 中 NULL 的区别2.1 C 语言中的 NULL// C 中 NULL 是 void* 类型#defineNULL((void*)0)intmain(){inta10;void*vpa;// C 允许 void* 隐式转换为其他指针类型int*ipvp;// 可以char*cpvp;// 可以// NULL 可以直接赋值int*pNULL;// 可以return0;}2.2 C 中的 NULL// C 中 NULL 是 0// C的严格类型检查不能直接将void* 类型的指针赋值给其他类型的指针所以NULL定义为 0#defineNULL0intmain(){inta10;void*vpa;// C 不允许 void* 隐式转换int*ipvp;// 错误int*ip(int*)vp;// 必须显式转换// NULL 实际上是 0int*pNULL;// 可以0 可赋值给指针intxNULL;// 可以0 可赋值给整数return0;}三、NULL 导致的二义性问题3.1 函数重载的二义性#includeiostreamusingnamespacestd;voidfun(inta){coutfun(int a)endl;}voidfun(char*p){coutfun(char* p)endl;}intmain(){fun(0);// 调用 fun(int)fun(NULL);// 调用 fun(int)因为 NULL 是 0// 问题程序员可能期望调用 fun(char*)return0;}输出fun(int a) fun(int a)3.2 更多二义性示例voidfunc(intx){coutintendl;}voidfunc(longx){coutlongendl;}voidfunc(void*p){coutpointerendl;}intmain(){func(0);// 调用 func(int)func(NULL);// 调用 func(int) 或 func(long)二义性// 某些编译器可能产生编译错误return0;}四、nullptr 的使用4.1 基本用法#includeiostreamusingnamespacestd;intmain(){// nullptr 可以直接赋值给 int* 和 char* 等类型int*pnullptr;// 可以char*cpnullptr;// 可以double*dpnullptr;// 可以void*vpnullptr;// 可以// nullptr 不能转换为整数// int x nullptr; // 错误// int y 0; // 正确// nullptr 是常量不可修改// nullptr 0; // 错误// 判空比较if(pnullptr){coutp is null pointerendl;}// sizeof nullptrcoutsizeof(nullptr) sizeof(nullptr)endl;coutsizeof(void*) sizeof(void*)endl;// 相同return0;}4.2 解决函数重载二义性#includeiostreamusingnamespacestd;voidfun(inta){coutfun(int a)endl;}voidfun(char*p){coutfun(char* p)endl;}intmain(){fun(0);// 调用 fun(int)fun(nullptr);// 调用 fun(char*) 明确是指针版本// fun(NULL); // 可能产生二义性return0;}输出fun(int a) fun(char* p)五、nullptr_t 类型5.1 std::nullptr_tnullptr的类型是std::nullptr_t定义在cstddef中。#includecstddef#includeiostreamusingnamespacestd;intmain(){// nullptr 的类型decltype(nullptr)npnullptr;// np 是 nullptr_t 类型// nullptr_t 可以转换为任何指针类型int*pnp;char*cpnp;// nullptr_t 只能转换为指针类型// int x np; // 错误// 函数重载 nullptr_tautofunc[](nullptr_t){coutnullptr_t parameterendl;};func(nullptr);// 调用 nullptr_t 版本return0;}5.2 nullptr_t 的特性#includecstddef#includeiostreamusingnamespacestd;intmain(){// 所有 nullptr_t 实例都等价nullptr_t np1nullptr;nullptr_t np2nullptr;// 可以比较if(np1np2){coutequalendl;// 输出 equal}// 可以转换为 boolif(!np1){coutnullendl;// 输出 null}// 可以作为函数参数类型autocheck[](nullptr_t np){coutReceived nullptrendl;};check(nullptr);return0;}六、nullptr 与 NULL 对比6.1 类型对比特性nullptrNULL(C)类型std::nullptr_tint本质是 0可赋值给指针可以可以可赋值给整数不可以可以函数重载区分可以区分指针和整数无法区分类型安全类型安全类型不安全可读性明确表示空指针可能是整数0

相关新闻