zoukankan      html  css  js  c++  java
  • homework-07

    http://www.cnblogs.com/zhuyp1015/category/370450.html

    http://wenku.it168.com/d_001049706.shtml

    http://blog.csdn.net/lancelet/article/details/7220558

    http://www.csdn.net/article/2012-05-15/2805585

    http://mindhacks.cn/2012/08/27/modern-cpp-practices/

    C++11的新特性

    最近学习了C++11的新特性,将学习内容整理下来,C++11的新特性

    一、右值引用,move语义,完美转发

    c++11引入一种新式引用,名曰右值引用,语法:Type&& , const Type&&,区别于之前的&标示的左值引用。为理解右值引用,先要理解左值和右值的概念。

    左值,在表达式中,表达式结束时候不会消失,如:obj , *ptr , ptr[index] , ++x

    右值,在表达式中,是临时的,表达式结束就会“蒸发”,如:1729 , x + y , std::string("meow") , x++ 

    区分左值和右值,还有另一种方法:能否取得其地址。

    如果能取得其地址,是左值,如:&obj , &*ptr , &ptr[index] , &++x是合法的,是左值;

    如果不能取得其地址,是右值,如:&1729 , &(x + y) , &std::string("meow") , &x++ 都是不合法的,是右值。

    左值引用和右值引用各包含modifiable value和const value,故可以分为4种引用形式:

    • modifiable lvalue reference
    • const lvalue reference
    • modifiable rvalue reference
    • const rvalue reference

    std::move是获得右值的方式,通过move可以将左值转为右值。

    二、Lambda函数与表示式

    在标准 C++,特别是当使用 C++ 标准程序库算法函数诸如 sort 和 find,用户经常希望能够在算法函数调用的附近定义一个临时的述部函数(又称谓词函数,predicate 

    function)。由于语言本身允许在函数内部定义类型,可以考虑使用函数对象,然而这通常既麻烦又冗赘,也阻碍了代码的流程。此外,标准 C++ 不允许定义于函数内部的类型被

    用于模板,所以前述的作法是不可行的。

    C++11 对 lambda 的支持可以解决上述问题。

    一个 lambda 函数可以用如下的方式定义:

      [](int x, int y) { return x + y; }

    这个不具名函数的回返类型是 decltype(x+y)。只有在 lambda 函数符合"return expression"的形式下,它的回返类型才能被忽略。在前述的情况下,lambda 函数仅能为一个述句。

    在一个更为复杂的例子中,回返类型可以被明确的指定如下:

      [](int x, int y) -> int { int z = x + y; return z + x; }

    Lambda函数体内需要什么变量,就在方括号中指明,方括号内容的含义:

    []// 沒有定义任何参数。使用未定义参数会导致错误。

    [x, &y]// x 以传值方式传入,y 以传引用方式传入。

    [&]// 任何被使用到的外部参数皆以引用方式使用。

    [=]// 任何被使用到的外部参数皆以传值方式使用。

    [&, x]// x 显式地以传值方式加以使用。其余参数以传入方式使用。

    [=, &z]// z 显式地以引用方式加以使用。其余参数以传值方式使用。

    在成员函数中指涉对象的 this 指针,必须要显式的传入 lambda 函数, 否则成员函数中的 lambda 函数无法使用任何该对象的变量或函数。

    [this]() { this->SomePrivateMemberFunction(); };

    三、类型推导

    有被明确初始化的变量可以使用 auto 关键字

    使用auto可以减少冗余代码,举例而言,程序员不用写像下面这样:

      for (vector<int>::const_iterator itr = myvec.cbegin(); itr != myvec.cend(); ++itr)  

    而可以用更简短的

      for (auto itr = myvec.cbegin(); itr != myvec.cend(); ++itr)

    这里的cbegin()和cend也是c++11新加入的,因为begin(),和end()函数在容器中都有两个,一个返回iterator,
    另一个返回const_iterator,因为有auto关键字,编译器将右值推导成哪个不明确,所以对容器内容只读时推荐使用cbegin()和cend()

    四、以范围为基础的 for 循环

    Boost C++ 定义了许多"范围 (range) "的概念。范围表现有如受控制的串行 (list),持有容器中的两点。有序容器是范围概念的超集 (superset),有序容器中的两个迭代器 (iterator) 也能定义一个范围。这些概念以及操作的算法,将被并入 C++11 标准程序库。不过 C++11 将会以语言层次的支持来提供范围概念的效用。for 述句将允许简单的范围迭代:
    int my_array[5] = {1, 2, 3, 4, 5};
    for(int &x : my_array)
    {
      x *= 2;
    }
    
    上面 for 述句的第一部份定义被用来做范围迭代的变量,就像被声明在一般 for 循环的变量一样,其作用域仅只于循环的范围。而在":"之后的第二区块,代表将被迭代的范围。这样一来,就有了能够允许 C-style 数组被转换成范围概念的概念图。这可以是 std::vector,或是其他符合范围概念的对象。

     五. 显示虚函数重载 override final关键字

    为防止子类重载的函数与基类函数不一致的情况发生,在编译期期捕获倒错误;

    C++11也提供关键字final,用来避免类被继承,或是基类的函数被改写。

    问题

    1. 右值的引入感觉上的确是为c++带来了比较好的改进,但是试图对一个右值写&来取指针只会导致语法错误,如果遇到这样的情况该怎么样做?
    2. lambda不怎么明白求教啊!
    3. 类型推导的auto算新特性吗?不明觉厉
    4. for的迭代器?不明白为什么要引入这个啊,感觉没什么改进的说。
    5. 个人一直以为虚函数就是一种特殊的重载,但是不明白这个改进怎么让编译器捕获到的?
    6. http://zhangjunxin520.blog.163.com/blog/static/3050370320116210101891/对于上述的博客里说的Bjarne Stroustrup(C++的创造者)最近评价C++11:”感觉像个新的语言“,个人感觉除了右值之外都没什么意义啊,完全没有改的必要,也许是我还不明白这些特性,求指教。
  • 相关阅读:
    愤怒
    Eclipse的调试功能的10个小窍门
    PL/SQL之基础篇
    PL/SQL之高级篇
    luogu P1015 回文数
    Noip2011 提高组 Day1 T3 Mayan游戏
    各种各样的——玄学卡常技巧
    北京清北 综合强化班 Day5
    [UVA12003] Array Transformer(分块,二分,暴力)
    [POJ3468] A Simple Problem with Integers(分块)
  • 原文地址:https://www.cnblogs.com/jun1022/p/3416966.html
Copyright © 2011-2022 走看看