美文网首页嵌牛IT观察
C++11新特性之新类型与初始化

C++11新特性之新类型与初始化

作者: babyL_f449 | 来源:发表于2017-11-26 19:15 被阅读0次

    姓名:雷潇 16030110083

    转载自:http://www.lai18.com/content/24569586.html

    【嵌牛导读】这是C++11新特性介绍的第一部分,比较简单易懂,但是也有一些有趣的地方。

    不想看toy code的读者可以直接拉到文章最后看这部分的总结。

    【嵌牛鼻子】数据类型的定义,指针

    【嵌牛提问】如何选取适当的数据类型才能满足存储的要求?

    【嵌牛正文】

    新类型

    long long类型

    C++11标准中新加入了long long类型属性,占用空间不小于long类型。测试代码如下:

    [cpp]view plaincopy

    longlarge = LONG_MAX;

    longlonglong_large = LLONG_MAX;

    longlonglong_long_large = 1LL << 63;

    cout<<"test long long:"<

    在我的机器上实测,long long类型和long类型同样使用64bit空间。

    nullptr字面量

    C++11标准中专门为空指针增加了nullptr字面量,同时不推荐再使用NULL或者0表示空指针。

    [cpp]view plaincopy

    int*p1 = nullptr;

    int*p2 = 0;

    int*p3 = NULL;

    cout<<"test nullptr: "<<(p1 == p2)<<'\t'<<(p1 == p3)<

    最终测试结果,nullptr和NULL和0是一样的。

    constexpr

    C++11标准中新增constexpr用于声明常量表达式,编译器会验证此变量的值是否是一个常量表达式。

    [cpp]view plaincopy

    intout_i = 0;// out_i定义于函数外部

    ...

    constexprintmf = 20;

    constexprintlimit = mf + 1;

    constexprint*p4 = &out_i;

    // the following would cause a make error

    // since large is not a constexpr

    //constexpr int wrong = large + 1;

    // since &in_j is not a constexpr;

    //int in_j = 0;

    //constexpr int *p5 = &in_j;

    值得注意的是,constexpr指针可以指向非常量变量,只要此变量定义于函数之外,因为这样的变量的指针(地址)是可以在编译期确定的。

    另外,下面的constexpr指针与const指针的含义是完全不同的:

    [cpp]view plaincopy

    constexprint*p6 = nullptr;// a const pointer point to an int

    // p6 = &out_i; // error: p6 is a constexpr

    constint*p7 = nullptr;// a pointer point to a const int

    第一个指针表示一个常量指针,即指针的值是常量;而第二个指针表示一个指向const int的指针,即指针指向的值是常量。

    constexpr还可以用于函数,constexpr函数是指能用于常量表达式的函数,它遵循以下几条约定:

    a.返回类型是字面值类型

    b.形参类型是字面值类型

    c.函数体中必须有且仅有一条return语句

    [cpp]view plaincopy

    constexprintsz() {return42; }

    constexprintnew_sz(intcnt) {returnsz() * cnt; }

    constexprintsize = sz();

    constexprintnsize = new_sz(mf);

    //constexpr int wrong_size = new_sz(out_i); // error: out_i is not a constexpr

    cout<<"test constexpr: "<

    noexcept

    noexcept可以用作异常指示符,用于指示一个函数是否会抛出异常。编译器并不检查使用了noexcept的函数是否真的不抛出异常,在运行时,如果一个使用noexcept承诺不抛出异常的函数实际抛出了异常,那么程序会直接终止。

    [cpp]view plaincopy

    voidno_except() noexcept

    {

    throw1;

    }

    // the following call will cause terminate

    //no_except();

    noexcept还可以带参数,noexcept(true)表示不会抛出异常,noexcept(false)表示可能抛出异常。

    同时noexcept还可以用作运算符,接受一个函数调用,返回一个bool值表示是否会抛出异常。noexcept运算符并不会对其实参进行求值。

    将noexcept运算符,结合带参数的noexcept指示符,可以得到如下常用法:

    [cpp]view plaincopy

    voidno_except2() noexcept(noexcept(no_except())){}

    cout<<"test noexcept: "<

    这种用法表示no_except2和no_except的异常说明保持一致。

    初始化

    列表初始化

    C++11新标准中为很多类型增加了列表初始化的功能。

    可以用列表初始化一个简单变量。

    [cpp]view plaincopy

    intsingle_int1 = 0;

    intsingle_int2 = {0};

    cout<<"test list initialization:\n"<

    可以用列表初始化一个容器(vector,list,map,set…)。

    [cpp]view plaincopy

    // vector/list list initialization

    vector v1 = {"ab","cd","ef"};

    list l2{"gh","ij","kl"};

    //vector v3("mn", "op", "qr"); // wrong initialization format

    cout<<"test vector/list list initialization:\n"<

    // map/set list initialization

    map m1 =

    {

    {"a","A"},

    {"b","B"},

    {"c","C"}

    };

    m1.insert({"d","D"});

    set s1 = {"a","b","c"};

    cout<<"test map/set list initialization:\n"<

    可以在使用new动态分配内存时使用列表初始化。

    [cpp]view plaincopy

    vector *pv =newvector{0, 1, 2, 3, 4};

    int*pi =newint[5]{0, 1, 2, 3, 4};

    cout<<"test new alloator using list initialization:\n"<<(*pv)[2]<<'\t'<

    可以在传入参数/函数返回值时使用列表初始化。

    [cpp]view plaincopy

    m1.insert({"d","D"});

    vector error_msg(inttyp)

    {

    switch(typ)

    {

    case1:

    return{"type1","msg1"};

    case2:

    return{"type2","msg2"};

    default:

    return{};

    }

    }

    pair get_pair(inttyp)

    {

    if(typ == 1)return{"key","value"};

    returnpair("default key","default value");

    }

    vector err_msg1 = error_msg(1);

    vector err_msg2 = error_msg(2);

    vector err_msg3 = error_msg(3);

    cout<<"test return value list initialization:\n"<

    pair p1 = get_pair(1);

    pair p2 = get_pair(2);

    cout<<"test return pair list initialization:\n"<

    类内成员初始化

    C++11标准中允许直接对类内成员进行初始化/列表初始化。

    [cpp]view plaincopy

    classInitClass

    {

    public:

    voidprint_class()

    {

    cout<

    }

    private:

    intfield1 = 1;

    intfield2;

    doublefield3 = 1.0;

    doublefield4;

    };

    classInitClassMgr

    {

    public:

    vector init_objs = {InitClass()};

    };

    InitClass test_class;

    cout<<"test class member initialization:\n";

    test_class.print_class();

    InitClassMgr mgr;

    cout<<"test class member of class type initialization:\n";

    mgr.init_objs[0].print_class();

    总结

    long long类型。

    nullptr字面量用于表示空指针。

    constexpr用于表示常量表达式。

    noexcept可以用于指示一个函数是否会抛出异常,同时可以用作运算符判定一个函数是否承诺不抛出异常。

    新增基础类型、容器类型、new分配内存时的列表初始化。构建临时变量时也可以直接使用列表初始化。

    可以直接对类内成员进行初始化/列表初始化。

    完整代码详见new_type_and_keywords.cppinitialize.cpp

    相关文章

      网友评论

        本文标题:C++11新特性之新类型与初始化

        本文链接:https://www.haomeiwen.com/subject/xwclbxtx.html