C++11: nullptr、默认函数的控制、lambda函数 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

   

    1 nullptr

    nullptr是nullptr_t类型的实例化,替代了传统的NULL,C++11的指针空值常量,

C++11: nullptr、默认函数的控制、lambda函数

    nullptr_t是指针空值类型,nullptr仅仅是nullptr_t的一个实例,nullptr_t的使用规则:

    1) 所有定义为nullptr_t类型的数据都是等价的,行为也完全一致

    2) nullptr_t类型数据可以隐式转换成任意一个指针类型

    3) nullptr_t类型类型不能转换为非指针类型,即使使用reinterpret_cast()的方式也是不可以的

    4) nullptr_t类型数据不适用于算术表达式

    5) nullptr_t类型数据可以用于关系运算表达式,但仅能于nullptr_t类型数据或者指针类型数据进行比较,当且仅当关系运算符为==、<=、>=等时返回true。

    下面的例子演示了上面的规则:

    #include 

    #include 

    using namespace std;

    int main()

    {

    // nullptr可以隐式转换为 char*

    char * cp = nullptr;

    // 不可转换为整型,而任何类型也不能转换为nullptr_t,

    // 以下代码不能通过编译

    // int n1 = nullptr;

    // int n2 = reinterpret_cast(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;

    // nullprt * 5;

    // 以下操作均可以正常进行

    sizeof(nullptr);

    typeid(nullptr);

    throw(nullptr);

    return 0;

    }

    虽然nullptr_t是个类型,但是在实例化模板的时候却不能实例化为任何指针:

    #include 

    using namespace std;

    template void g(T* t) {}

    template void h(T t) {}

    int main()

    {

    g(nullptr);            // 编译失败, nullptr的类型是nullptr_t,而不是指针

    g((float*) nullptr);   // 推导出T = float

    h(0);                  // 推导出T = int

    h(nullptr);            // 推导出T = nullptr_t

    h((float*)nullptr);    // 推导出T = float*

    }

    nullptr和void*所占内存空间一样,但是nullptr是个编译期常量,而(void*)0是强制转换表达式,nullptr到任何指针的转换是隐式的,而(void*)0则必须经过类型转换后才能使用,nullptr可以完全替换null和(void*)0,

电脑资料

C++11: nullptr、默认函数的控制、lambda函数》(https://www.unjs.com)。

    int* ptr=(void*)0;//错误

    int* p=nullptr;//正确

    nullptr_t对象的地址可以被用户使用,但是用户确却不能获得nullptr的地址,因为nullptr是右值常量,但是C++11没有禁止声明一个nullptr的右值引用并打印该右值引用的地址。

    2 默认函数的控制=default、=delete

    自定义的类型一但显示定义了构造函数后将不再是POD,即使函数体内什么也没有定义,但是可以通过=default恢复编译器默认的构造版本。

    #include 

    #include 

    using namespace std;

    class TwoCstor {

    public:

    // 提供了带参数版本的构造函数,再指示编译器

    // 提供默认版本,则本class依然是POD类型

    TwoCstor() = default;//TwoCstor(){}函数体内什么也没定义也不是POD

    TwoCstor(int i): data(i) {}

    private:

    int data;

    };

    int main(){

    cout << is_pod::value << endl;

    }

    可以在函数后面加=delete禁止函数的生成,如下禁止拷贝构造函数:

    #include 

    #include 

    using namespace std;

    class NoCopyCstor {

    public:

    NoCopyCstor() = default;//编译器默认的构造函数

    // 使用 "= delete" 同样可以有效阻止用户

    // 错用拷贝构造函数

    NoCopyCstor(const NoCopyCstor &) = delete;//禁止拷贝构造

    };

    int main(){

    NoCopyCstor a;

    NoCopyCstor b(a);   // 无法通过编译

    }

    =default和=delete可以在类外定义,这样就可以在不同的cpp文件中实现不同的版本

    class DefaultedOptr{

    public:

    // 使用"= default"来产生缺省版本

    DefaultedOptr() = default;

    // 这里没使用"= default"

    DefaultedOptr & operator = (const DefaultedOptr & );//类内不需要=default

    };

    // 在类定义外用"= default"来指明使用缺省版本

最新文章