zoukankan      html  css  js  c++  java
  • c++ 11部分新特性小结

    【shared_ptr】

    c++ 11模板库的<memory>头文件中定义的智能指针,即 shared_ptr 模板,用于自动释放 new 动态分布的内存空间。

    只要将new运算符返回的指针 ptr 交给一个shared_ptr对象托管,就不必写 delete ptr 语句,托管 ptr 指针的 shared_ptr 对象在消亡时会自动执行 delete ptr。

    shared_ptr 对象能像指针 ptr 一样使用,即 *shared_ptr 就是 *ptr。

    当对shared_ptr进行拷贝和赋值操作每个shared_ptr都会记录它所指向对象的个数,一般称之为引用计数。

    当进行拷贝操作时他们所指向的对象的引用计数都会增加,一旦一个shared_ptr的引用计数变为0,它就会自动释放自己所管理的对象。

     

    A* a = new A();

    std::shared_ptr<A> sp(a); // *sp 等价于 *a

    // delete a;

     

    【static_assert】

    编译时期的断言,因此叫静态断言。使用static_assert可以在编译时期发现更多的错误,用编译器来强制保证一些约束。

    static_assert(expr,str);

    其中expr为表达式,str为提示信息。当expr为true时,继续编译; 当expr为false时,中断编译,显示提示信息str。

     

    const int a = add(3, 4);

    static_assert(a == 8, "tongyishu"); // 报错:error: static assertion failed: tongyishu

     

    【constexpr】

    constexpr 为常量表达式,即在编译期可求值的表达式。

    constexpr 可以用来修饰变量、函数、构造函数,一旦以上任何元素被constexpr修饰,就等同于告诉编译器:请大胆地将我看成编译时就能得出常量值的表达式去优化我。

     

    constexpr int a = 3 * 4 + 8; // ok

    constexpr int a = add(3, 4); // error

     

    constexpr int add(int a, int b) { return a + b; }

    constexpr int a = add(3, 4); // ok

     

    【auto】

    使用auto的时候,编译器根据上下文情况,确定auto变量的真正类型。

    int a = 0;

    int b = 0;

    auto c = a + b; // c 的类型为 int

     

    【for】

    一个例子说明 for 循环的遍历用法:

    int array[] = { 0, 1, 2, 3 };

    for (auto a : array) {

      std::cout << a << std::endl;

    }

     

    【static_cast】

    1. 基本数据类型之间的转换,如把int转换成char,把int转换成enum。
    2. 用于类层次结构中基类和子类之间指针或引用的转换。
        进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
        进行下行转换(把基类指针或引用转换成子类指针或引用)是不安全的。
    3. 把void指针转换成目标类型的指针。

     

    short s_val = 0;

    int i_val = static_cast<int>(s_val);

     

    【const_cast】

    常量指针被转化成非常量指针,并且仍然指向原来的对象;
    常量引用被转换成非常量引用,并且仍然指向原来的对象;
    const_cast的作用是用来去除表达式里面的 const 限定。

     

    const int var = 0;

    // var = 1; 报错

    int* ptr = const_cast<int*>(&var);

    *ptr = 1;

     

    【nullptr】

    在 c++ 中 NULL 的定义如下:

    #ifdef __cplusplus

    #define NULL 0

    #else

    #define NULL ((void *)0)

    #endif

    这样定义 NULL 的原因:c++ 是强类型语言,不能将 void* 类型的指针隐式转换成其他指针类型,而又为了解决空指针的问题,所以 c++ 中引入 0 来表示空指针

    由于以上 NULL 的定义,在函数重载时会出现问题:

    void myfunc(int var);

    void myfunc(int* var);

    而 nullptr 就是用来地解决这类问题:

    myfunc(0); // int var

    myfunc(nullptr); // int* var

     

    【Lamda】

    Lamda类似于匿名函数,在使用 c++ 的 STL 时往往会用到大量的函数对象,为此要编写很多函数对象类,有的函数对象类只用来定义了一个对象,而且这个对象也只使用了一次,编写这样的函数对象类就有点浪费。
    对于只使用一次的函数对象类,能否直接在使用它的地方定义呢?Lamda 表达式能够解决这个问题。

    Lamda表达式的定义:

    [要捕获的外部变量](参数列表)->返回值{语句块}

    [=](int x, int y)->bool{return x < y;}

     

    Lamda表达式的使用:

    int a[4] = { 0, 1, 2, 3};

    sort(a, a + 4, [=](int x, int y)->bool{return x < y;});

     

    int a = 0;

    int b = 1;

    auto func = [=](int c) {

    return a + b + c;

    }

    std::cout << func(2) << std::endl; // 输出 3

     

    []               什么也没有捕获
    [a, &b]      按值捕获a,按引用捕获b
    [&]            按引用捕获任何用到的外部变量
    [=]            按值捕获任何用到的外部变量
    [a, &]        按值捕获a, 其它的变量按引用捕获
    [&b, =]     按引用捕获b,其它的变量按值捕获
    [this]         按值捕获this指针

     

    【内联函数】

    内联函数的定义:在返回值之前加上inline关键字。

    inline int add(int a, int b) { return a + b; }

    内联函数和普通函数的区别在于:当编译器处理调用内联函数的语句时,不会将该语句编译成函数调用的指令,而是直接将整个函数体的代码插人调用语句处,就像整个函数体在调用处被重写了一遍一样。

  • 相关阅读:
    [ Algorithm ] N次方算法 N Square 动态规划解决
    [ Algorithm ] LCS 算法 动态规划解决
    sql server全文索引使用中的小坑
    关于join时显示no join predicate的那点事
    使用scvmm 2012的动态优化管理群集资源
    附加数据库后无法创建发布,error 2812 解决
    浅谈Virtual Machine Manager(SCVMM 2012) cluster 过载状态检测算法
    windows 2012 r2下安装sharepoint 2013错误解决
    sql server 2012 数据引擎任务调度算法解析(下)
    sql server 2012 数据引擎任务调度算法解析(上)
  • 原文地址:https://www.cnblogs.com/tongyishu/p/13049739.html
Copyright © 2011-2022 走看看