langShift

现代 C++ 特性

自 C++11 以来,C++ 经历了显著的演进,新的标准(C++14、C++17、C++20、C++23)引入了强大的特性,使语言更安全、更具表达力、更高效。这些现代特性通常提供了替代旧的、更容易出错的惯用语的方法,并使 C++ 更接近 JavaScript 等语言提供的便利性,同时保留其性能优势。

C++11/14/17/20 新特性概述

以下是近期 C++ 标准中引入的一些关键特性的简要概述:

  • C++11: Lambda 表达式、auto 关键字、右值引用和移动语义、nullptrstd::threadstd::chronostd::unique_ptrstd::shared_ptr、基于范围的 for 循环、初始化列表。
  • C++14: 泛型 Lambda、constexpr 改进、变量模板。
  • C++17: 结构化绑定、if constexprstd::optionalstd::variantstd::string_view、并行算法。
  • C++20: 概念、范围、协程、模块、std::spanstd::jthread

Lambda 表达式

Lambda 表达式(或简称“Lambda”)是匿名函数,可以内联定义并用于函数对象预期的地方。它们对于简短、局部化的操作非常有用,尤其是在算法中。

  • 语法: [捕获列表](参数) -> 返回类型 { 函数体 }
  • 捕获列表: 指定 Lambda 可以访问周围作用域中的变量。
正在加载...

移动语义和右值引用

移动语义 (C++11) 允许高效地将资源(如动态分配的内存)从一个对象转移到另一个对象,而无需昂贵的深层复制。这通过右值引用 (&&) 实现。

  • 左值: 指的是内存位置并具有身份的表达式(例如,变量)。
  • 右值: 不指内存位置且没有身份的表达式(例如,临时对象、字面量)。
  • std::move 将左值转换为右值引用,表示其资源可以被移动。
正在加载...

auto 关键字和类型推导

auto 关键字 (C++11) 允许编译器从其初始化器推导变量的类型。这可以使代码更简洁、更具可读性,尤其是在处理复杂类型时。

正在加载...

基于范围的 for 循环

基于范围的 for 循环 (C++11) 提供了一种更简单、更具可读性的方式来迭代范围内的元素(如容器、数组或初始化列表),而无需明确使用迭代器。

正在加载...

初始化列表

初始化列表 (C++11) 提供了一种统一的方式来初始化对象,尤其是容器。它们使用花括号 {}

正在加载...

与 JavaScript 现代特性的比较

许多现代 C++ 特性旨在提供与 JavaScript 相似的表达力和便利性,同时保持 C++ 的核心优势。

特性JavaScript 等效项C++ 现代特性
匿名函数箭头函数、匿名函数Lambda 表达式
类型推导动态类型、let/constauto 关键字
迭代for...offorEach基于范围的 for 循环
资源管理垃圾回收、finally移动语义、智能指针 (RAII)
数据初始化数组/对象字面量初始化列表

虽然 JavaScript 通过动态类型和运行时解释实现了大部分灵活性,但现代 C++ 通过编译时特性(模板、auto、Lambda)和明确的资源管理(移动语义、智能指针)实现了类似的表达力。这使得 C++ 能够提供高级抽象和低级控制,通常具有卓越的性能。


练习题:

  1. C++ 中的 Lambda 表达式是什么?提供一个示例,说明它们如何简化代码,与传统函数对象相比。
  2. 解释移动语义和右值引用的概念。它们如何促进 C++ 中的性能优化?
  3. 描述在现代 C++ 代码中使用 auto 关键字和基于范围的 for 循环的好处。它们如何提高可读性和简洁性?

项目构想:

  • 重构现有的 C++ 程序(或编写一个新程序),该程序处理数据集合(例如,自定义对象的 std::vector)。利用现代 C++ 特性,例如用于自定义排序或过滤的 Lambda 表达式、用于类型推导的 auto,以及用于迭代的基于范围的 for 循环。如果适用,演示在转移大型对象所有权时使用移动语义。