- C++ 开发 Web 服务框架
- 1 小时入门增强现实技术
- C++ 实现高性能内存池
- GDB 简明教程
- C++ 实现太阳系行星系统
- C++11/14 高速上手教程
- C 语言实现 Linux Shell 命令解释器
- C++ 打造 Markdown 解析器
- C 语言实现文件类型统计程序
- C 语言实现 Linux touch 命令
- C 语言入门教程
- C 语言实现多线程排序
- 多线程生产者消费者模型仿真停车场
- C++实现运动目标的追踪
- C 语言实现 Linux 网络嗅探器
- 100 行 C++ 代码实现线程池
- C 语言实现聊天室软件
- C 语言实现 Linux who 命令
- C 语言实现 Linux cp 命令
- C++实现第一人称射击游戏
- C++ 实现银行排队服务模拟
- 数据结构(新版)
- 软件工程(C 编码实践篇)
- C 语言制作简单计算器
- C 语言版 flappy_bird
- C 语言编写万年历
- C 语言版扫雷游戏
- C 语言实现一个支持 PHP 的简易 WEB 服务器
- C 语言制作 2048
- C 语言模拟 ATM 自动取款机系统
- Linux 系统编程
- C 语言利用 epoll 实现高并发聊天室
- C 语言快速实现五子棋
- C 语言实现 ping 程序
- 简单词法分析器(C++语言)
第 1 节 C++ 11/14 高速上手教程 - C++11/14 简介
一、概述
目标读者
本教程假定读者已经熟悉了传统 C++ ,至少在阅读传统 C++ 代码上不具备任何困难。
引言
C++ 算是一个用户群体比较大的语言了,从 C++98 到 C++11 经历了长达十年多之久的积累,C++14 则是作为对 C++11 的重要补充和优化,所有这些新标准中扩充的特性,给 C++ 这门语言注入了新的活力。
那些还在坚持使用 传统 C++ (本教程把 C++98 及其之前的 C++ 特性均称之为传统 C++)而未接触过 C++11/14 的 C++ 程序员在见到诸如 Lambda 表达式这类全新特性时,甚至会流露出『学的不是同一门语言』的惊叹之情。
C++1x (本教程中指 C++11/14, 甚至 C++17) 为传统 C++ 注入的大量特性使得整个 C++ 变得更加像一门现代化的语言。C++1x 不仅仅增强了 C++ 语言自身的可用性, auto
关键字语义的修改使得我们更加有信心来操控极度复杂的模板类型。同时还对语言运行期进行了大量的强化,Lambda 表达式的出现让 C++ 具有了『匿名函数』的『闭包』特性,而这一特性几乎在现代的编程语言(诸如 Python/Swift/... )中已经司空见惯,右值引用的出现解决了 C++ 长期以来被人诟病的临时对象效率问题等等。
C++1x 为自身的标准库增加了非常多的工具和方法,诸如在语言层面上提供了 std::thread
支持了并发编程,在不同平台上不再依赖于系统底层的 API,实现了语言层面的跨平台支持; std::regex
提供了完整的正则表达式支持等等。
C++98 已经被实践证明了是一种非常成功的『范型』,而 C++1x 的出现,则进一步推动这种范型,让 C++ 成为系统程序设计和库开发更好的语言。
> 提示:本课程所有代码至少需要开启 -std=c++11
选项来支持 C++11 相关特性,在介绍 C++14 特性时的相关代码需要开启 -std=c++14
的编译选项,例如: > > > g++ main.cpp -std=c++11 > g++ main.cpp -std=c++14 >
> > 推荐所有代码均使用 -std=c++14
选项进行编译。
二、教程目录
本教程虽号称高速上手教程,但实际上对 C++11/14 的相关特性做了一个较为全面的介绍,读者可以自行根据下面的目录选取感兴趣的内容进行学习,快速熟悉需要了解的内容,这从某种意义上来说,也算是高速上手了。
这些特性并不需要全部掌握,只需针对特定的应用场景,学习、查阅最适合自己的新特性即可(但 总结部分依然给出了建议学习的特性 )。
值得一提的是, 本教程在介绍这些特性的过程中,尽可能简单明了的介绍了这些特性产生的历史背景和技术需求,这为理解这些特性、运用这些特性提供了很大的帮助。
- C++11/14 简介
- 概述
- 教程目录
- 被弃用的特性
- 与 C 的兼容性
- 语言可用性的强化
nullptr
与constexpr
- 类型推导
auto
decltype
- 尾返回类型、
auto
与decltype
配合
- 区间迭代
- 基于范围的 for 循环
- 初始化列表
std::initializer_list
- 统一初始化语法
- 模板增强
- 外部模板
- 尖括号
>
- 类型别名模板
- 变长参数模板
- 面向对象增强
- 委托构造
- 继承构造
- 显式虚函数重载
override
final
- 显式禁用默认函数
- 强类型枚举
- 语言运行期的强化
- lambda 表达式
- lambda 表达式基础
- 值捕获
- 引用捕获
- 隐式捕获
- 表达式捕获
- 泛型 lambda
- lambda 表达式基础
- 函数对象包装器
- std::function
- std::bind/std::placeholder
- 右值引用
- 左值、右值的纯右值、将亡值、右值
- 右值引用和左值引用
- 移动语义
- 完美转发
- lambda 表达式
- 对标准库的扩充: 新增容器
std::array
std::forward_list
std::unordered_set
std::unordered_map
std::tuple
- 基本操作
- 运行期索引
- 合并与迭代
- 对标准库的扩充: 智能指针和引用计数
- 引用计数
std::shared_ptr
std::make_shared
std::unique_ptr
std::weak_ptr
- 对标准库的扩充: 正则表达式库
- 正则表达式简介
- 普通字符
- 特殊字符
- 限定符
std::regex
及其相关std::regex
std::regex_match
std::match_results
- 正则表达式简介
- 对标准库的扩充: 语言级线程支持
std::thread
std::mutex
std::unique_lock
std::future
std::packaged_task
std::condition_variable
- 其他杂项
- 新类型
long long int
noexcept
的修饰和操作- 字面量
- 原始字符串字面量
- 自定义字面量
- 新类型
- 扩展主题: C++17 简介
- 主要入选特性
- 非类型模板参数的
auto
std::variant<>
- 结构化绑定(Structured bindings)
- 变量声明的强化
- 非类型模板参数的
- 未入选特性
- Concepts
- 主要入选特性
三、被弃用的特性
在学习 C++1x 之前,我们先了解一下从 C++11 开始,被弃用的主要特性:
> 注意 :弃用不等于废弃,只是用于暗示程序员这些特性将从未来的标准中消失,应该尽量避免使用。但是,已弃用的特性依然是标准库的一部分,并且出于兼容性的考虑,这些特性其实会『永久』保留。
- 如果一个类有析构函数,为其生成拷贝构造函数和拷贝赋值运算符的特性被弃用了。
- 不再允许字符串字面值常量赋值给一个
char *
。如果需要用字符串字面值常量赋值和初始化一个char *
,应该使用const char *
或者auto
。
char *str = "hello world!"; // 将出现弃用警告
- C++98 异常说明、
unexcepted_handler
、set_unexpected()
等相关特性被弃用,应该使用noexcept
。 auto_ptr
被弃用,应使用unique_ptr
。register
关键字被弃用。bool
类型的++
操作被弃用。- C 语言风格的类型转换被弃用,应该使用
static_cast
、reinterpret_cast
、const_cast
来进行类型转换。
还有一些其他诸如参数绑定(C++11 提供了 std::bind
和 std::function
)、 export
等特性也均被弃用。前面提到的这些特性 如果你从未使用或者听说过,也请不要尝试去了解他们,应该向新标准靠拢 ,直接学习新特性。毕竟,技术是向前发展的。
四、与 C 的兼容性
出于一些不可抗力、历史原因,我们不得不在 C++ 中使用一些 C 语言代码(甚至古老的 C 语言代码),例如 Linux 系统调用。在 C++11 出现之前,大部分人当谈及 『C 与 C++ 的区别是什么』时,普遍除了回答面向对象的类特性、泛型编程的模板特性外,就没有其他的看法了,甚至直接回答『差不多』,也是大有人在。下面的韦恩图大致上回答了 C 和 C++ 相关的兼容情况:
从现在开始,你的脑子里应该树立 『C++ 不是 C 的一个超集』 这个观念(而且从一开始就不是)。在编写 C++ 时,也应该尽可能的避免使用诸如 void*
之类的程序风格。而在不得不使用 C 时,应该注意使用 extern "C"
这种特性,将 C 语言的代码与 C++代码进行分离编译,再统一链接这种做法,例如:
// foo.h
#ifdef __cplusplus
extern "C" {
#endif
int add(int x, int y);
#ifdef __cplusplus
}
#endif
// foo.c
int add(int x, int y) {
return x+y;
}
// main.cpp
#include "foo.h"
int main() {
add(1, 2);
return 0;
}
应先使用 gcc
编译 C 语言的代码:
gcc -c foo.c
编译出 foo.o 文件,再使用 g++
将 C++代码和 .o
文件链接起来(或者都编译为 .o
再统一链接):
g++ main.cpp foo.o -o main
> 本节代码: > > > http://labfile.oss.aliyuncs.com/courses/605/1.zip >
进一步阅读的参考资料
- C++ 语言导学. Bjarne Stroustrup
- C++ 历史
- C++ 1x 特性在 GCC/Clang 等编译器中的支持情况
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论