0%

C++11 的重大改变

The Biggest Changes in C++11 (and Why You Should Care),译文:C++11 的重大改变

事实上,核心 C++11 已经有了很大的改变。C++11 标准库同样增加了新的内容。捎带一句,C++11, also formerly known as C++0x …

Core

事实上,核心 C++11 已经有了很大的改变。现在它支持 lambda 表达式,自动类型推断,统一的初始化语法,委托构造函数,已删除和默认函数声明,nullptr,以及最重要的,右值引用——一种预言将会改变创造和处理对象方法的技术。

Lambda 表达式

lambda 的函数调用运算符为 const-by-value,但对 mutable 关键字的使用可将其取消。

自动类型推断和 decltype

赋予 auto 关键词新生: 数据存储类型

auto 自动推导类型,轻度用户(不涉及模板)谨慎使用,在书写便利和代码易读两者之间寻求,滥用降低代码可读性。

注意使用的限制

1
2
3
4
5
6
size_t length = 10;
int diff = 0 - length;
auto diff2 = 0 - length;
// diff != diff2
cout << (0 - length) << endl;
// NOTE 并未像我们预期的那这样子输出 -10

统一初始化语法

列表初始化:初始化操作的多种变体是令人感觉困扰的重要原因之一。C++11 使用统一的大括号标记清除了这种混乱。

POD (程序设计) - wikipedia

看了以上几篇帖子之后,知道了几个名词:Aggregate 和 POD,trivial 和 standard-layout。但详细的概念很是混乱,其中一条条的“是与不是”、“有与没有”难道是让人用来背诵记忆的吗?实用主义不要求学究钻研,编码过程用到了再回来复习。目前,水过不学了。其实真要较真的话,应该直接去找 C++ 的新标准,网上的终究是个参考,会有出入。

删除和默认函数

  • 多看书,多写代码

nullptr

  • 在此之前是什么样子?会有什么问题?深度探索一下。

  • c++11 中的 nullptr 详解

  • NULL 和 0 - 蓝色的回答

    • 不推荐使用宏,甚至不承认宏。包括 NULL,C++标准是没有承认 NULL 是 null pointer constant 的。
    • 赋予 null pointer,应该是使用 0,而非 NULL

委托构造函数

右值引用

  • 区分“左值”和“右值”。引用自 右值引用 - wikipedia

    在C++11提出右值引用之前,C++03及更早的C++标准中,表达式的“值分类”(value categories)属性为左值或右值。左值是对应(refer to)内存中有确定存储地址的对象的表达式的值,而右值是所有不是左值的表达式的值。因而,右值可以是字面量、临时对象等表达式。能否被赋值不是区分C++左值与右值的依据。C++的const左值是不可赋值的;而作为临时对象的右值可能允许被赋值。左值与右值的根本区别在于是否允许取地址&运算符获得对应的内存地址

  • 移动语义?学习 C++ Prime

    • 移动构造函数、移动赋值运算符

      C++11 标准库大量使用了移动语义。许多算法和容器也为移动语义做了优化。

  • 【译】详解 C++ 右值引用,阅读笔记如下

    1. 概述中 # &foobar() 是取 foobar() 函数执行结果的地址,而不是函数指针,&foobar 才是函数指针。

    2. 右值引用,总算渐渐明朗了。但前提是分清左值/右值。

      const 常量是左值,还是右值呢?——左值,因为 const int max = 100; 中 max 是可以使用 & 取地址的。

    3. move语义# 中“当赋值操作符的右边是右值的时候,我们希望赋值操作符被定义成下面这样:”,醍醐灌顶啊

      此处的右值,在后续代码中可能会再次被用来给变量赋值吗?

      “move语义:当一个变量(a)作为拷贝构造函数或者赋值的来源时,这个变量要么就是以后都不会再使用,要么就是(使用时)作为赋值操作的目标(a = b)。”

      也就是,这个变量不能再用了。

      ——参考 右值引用是右值吗?#

      “move语义的重点在于将其应用于那些不重要的东西上面,那些move之后会马上销毁而不会被再次用到的东西上面。”

    4. 强制move语义# 中:

      C++11中的swap函数是这样的:…

      swap函数不能只做 a = std::move(b); 吗?

      值得注意的是对那些没有实现move语义的类型来说(没有针对右值引用重载拷贝构造函数和赋值操作符),新的swap仍然和旧的一样。

      可能只是为了兼容。参考 Debian8Light 代码验证。

    5. 右值引用是右值吗# 中读不懂:

      理论上来说goo()所引用的对象也可能在X x = goo();后被访问的到。但是回想一下,这种行为不正是我们想要的吗?我们也想随心所欲的在左值上面使用move语义。

    6. move语义与编译器优化# 暂时读不懂

    7. 完美转发相关内容暂时未看,涉及范型编程之泛型函数

Library

2003年,C++ 以库技术报告 1(TR1)的形式经历了一次大型重构。TR1 包含了新的容器类(unordered_setunordered_mapunordered_multisetunordered_multimap)和许多新的库,例如正则表达式,元组,函数对象包装器。随着 C++11 的颁布,TR1 连同新的库一起正式集成到 C++ 标准中。下面是 C++11 标准库的特性:

线程库

毫无疑问,从程序员角度看,C++11 最重要的改进就是并发。

新的智能指针类

C++98 只定义了一个智能指针类 auto_ptr,而这个类现在已经被废弃了。

C++11 包含了新的智能指针类:shared_ptrweak_ptr 和最近新加的 unique_ptr

weak_ptr 是多线程下,判断某一(在多个线程中共享的)对象是否 alive 的唯一方法。

新的算法

THE END

延伸阅读: