[C++] 判断指针为空方法的比较(NULL, 0, nullptr)

        我们使用C++编码时,经常会用到指针。在使用指针之前,对指针进行判空操作是一种规范编码的行为。C++中判断指针是否为空有3中方法(NULL, 0, nullptr),我们接下来分别对他们进行比较。

1. NULL

        NULL是C语言的内容,在C语言中,NULL的定义为:#define NULL ((void *)0)。因此,我们写 int* p = NULL; 时,NULL实际上是一个void*指针,通过隐式转换成int*指针。但是,采用C++编译器来编译的话是要出错的。因为C++是强类型的,void*不能通过隐式转换成其他类型的指针。

2. 0

        由于C++中不能将void*类型的指针隐式转换成其他类型的指针,为了解决空指针的问题,C++引入0来表示空指针。同时也将NULL定义为0。在vcruntime.h头文件中定义如下:

#ifndef NULL
    #ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif
#endif

        因此,在C++中NULL就是0,但是绝大多数C++书本都会推荐直接使用0来表示空指针,而不是NULL。为什么呢?接下来,我们举例说明:

// 在test.h中定义两个重载函数

void DoSomething(type1 a, type2* b);

void DoSOmething(type1 a, int i);

// 在Person.cpp中,希望调用 void DoSomething(type1 a, type2* b)

person.DoSomething(a, 0); // 写法1

person.DoSomething(a, NULL); // 写法2

       很显然,以上两种写法都不能实现我们的需求。但是,在查找错误的时候,写法1比写法2更直观,更容易被发现问题。写法2中的NULL不够明显,容易让我们失去警觉性。

3. nullptr

       虽然上面我们说0比NULL可以让我们更加警觉,但是我们并没有避免这个问题。这个时候C++ 11的nullptr就很好的解决了这个问题,直接使用 DoSomething(a, nullptr); 即可。C++中nullptr的定义如下:

const    //修饰类nullptr_t后面定义的nullptr对象
class nullptr_t
{
public:
    template<class T>               //该模板函数是在重载 类型转换运算符"()"
    inline operator T*() const      //这是一个类型转换函数,把0的类型转换成T*的类型
        { return 0; }               //C++规定转换函数不能写返回类型,
                                    //返回的类型就是operator后面跟的类型
 
    template<class C, class T>
    inline operator T C::*() const  //T C::*是指向数据成员的指针类型
        { return 0; }               
 
private:
    void operator&() const;         //??不懂
} nullptr = {};                     //= {} 是C++ 11的语法,代表给这个变量初始化

       从上述定义可以看出,nullptr是一个“指针空值类型”的常量。”指针空值类型“被命名为nullptr_t,它在stddef.h头文件中定义如下:

#ifdef __cplusplus
    namespace std
    {
        typedef decltype(__nullptr) nullptr_t;
    }

    using ::std::nullptr_t;
#endif

       这里用到了decltype类型说明符,它的作用是选择并返回操作数的数据类型。编译器分析表达式并得到它(__nullptr)的类型,却不实际计算表达式的值。由于nullptr是有类型的,且nullptr类型数据可以隐式转换成任意一个指针类型,因此如果编译器支持nullptr,那我们就优先使用nullptr。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值