• C++11 nullptr与nullptr_t


      参考《深入理解C++11》

      NULL是一个宏定义,在传统C头文件stddef.h中定义如下:

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

      可以看到,NULL可能被定义为字面常量0,或者定义为无类型指针(void*)常量。这就使得在使用NULL时有些问题:

       在main函数中,f(NULL)调用的起始是第二个函数,因为在C++98中,字面常量0具有二义性:既可以是一个整型,也可以是一个无类型指针(void*)。如果想要调用f(char*)的话,需要对字面常量0进行强制类型转换:(void*)0 然后再调用,否则编译器总会优先把0看做一个整型常量。

    nullptr_t的定义:头文件:<cstddef>

      typedef decltype(nullptr) nullptr_t;

      使用nullptr_t时必须包含头文件:<cstddef>,但是使用nullptr时则不用,因为nullptr是关键字。nullptr是有类型的,且仅可以被隐式转化为指针类型,在编写C++11代码时,使用nullptr替换NULL将使得代码更健壮。

    • nullptr:指针空值常量
    • nullptr_t:指针空值类型,也就是nullptr的类型,见上面的定义

    nullptr_t注意事项:

     示例代码:

        char* cp = nullptr;
    
        //不可转换为整型,而任何类型也不能转换为nullptr_t
        //以下代码不能通过编译
        //int n1 = nullptr;
        //int n2 = reinterpret_cast<int>(nullptr);
    
        //nullptr与nullptr_t类型变量可以作比较
        //当使用 ==  <=  >=符号比较时返回true
        nullptr_t nptr;
        if (nptr == nullptr)
        {
            cout << "nullptr_t nptr == nullptr" << endl;
        }
        else
        {
            cout << "nullptr_t nptr != nullptr" << endl;
        }
        if (nptr < nullptr)
            cout << "nullptr_t nptr < nullptr" << endl;
        else
            cout << "nullptr_t nptr !< nullptr" << endl;
    
        //不能转换为整型或bool类型,以下代码不能通过编译
        //if(0 == nullptr)
        //if(nullptr)
    
        //不能进行算术运算,以下代码不能通过编译
        //nullptr += 1;
        //nullptr *5;
    
        //以下操作均可正常运行
        size_t size1 = sizeof(nullptr);
        typeid(nullptr);
        throw(nullptr);

    注:如果上述代码注释部分能通过编译,可能是编译器版本不够新,在C++11中不允许上述注释代码。

       虽然nullptr_t看起来像是个指针类型,但是在把nullptr_t应用于模板中时,模板会把它作为一个普通的类型来进行推导,并不会将其视为T*指针。

    template<typename T>
    void g(T* t){}
    
    template<typename T>
    void h(T t){}
    
    int main(int argc, char *argv[])
    {
        g(nullptr);         //编译失败,nullptr的类型是nullptr_t,而不是指针
        g((float*) nullptr);//推导出T=float
    
        h(0);               //推导出T=int
        h(nullptr);         //推导出T=nullptr_t
        h((float*)nullptr); //推导出T=float*
    }
  • 相关阅读:
    【2018 “百度之星”程序设计大赛
    分班级(经典二分)
    【2018 “百度之星”程序设计大赛
    【zznu-夏季队内积分赛3-J】追忆
    常见网络名词解释
    【zznu-夏季队内积分赛3-G】2333
    【zznu-夏季队内积分赛3-F】学无止境
    【zznu-夏季队内积分赛3-I】逛超市
    html/css/javascript练习代码
    花生壳免费域名80端口无法访问问题处理
  • 原文地址:https://www.cnblogs.com/zyk1113/p/13489015.html
Copyright © 2020-2023  润新知