QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

C++ 实用指南

  • 2021-07-22
  • 本文字数:4363 字

    阅读完需:约 14 分钟

C++实用指南

C++发展得非常快!例如,C++标准的页数从 C++98/03 的 879 页增加到了 C++20 的 1834 页,多了近 1000 页!更重要的是,C++每次修订后,我们都会获得几十个新特性。你需要学习所有这些东西才能写出好代码吗?如何在当今的 C++世界中保持理智?

介绍


你可能知道 C++是一种复杂的语言。我甚至发现了一整页Wiki是讲对 Cpp 的批判的。现代 C++甚至为生态添加了更多内容。


以下是我之前提到的规范页数的完整数据:


  • C++98/03-879,N1905,2005 年 10 月

  • C++11-1324,最后草案,N3337,2012 年 1 月

  • C++14-1368,最后草案,2014 年 11 月

  • C++17-1586,草案,N4606

  • C++20-1834,草案,N4861



看起来 C++17 几乎比 C++98/03“大”了 80%,而 C++的最新草案比 C++03 多了将近 1000 页。你可以抱怨增加的这些复杂性,想学好所有这些东西也很困难。但这有那么可怕吗?面对这样的情况,你能做些什么?


首先,我们来看看你在 C++中可能会遇到的一些问题。

一些问题


仅举几例:


  • 节奏太慢

  • 节奏太快

  • 特性的混乱/复杂性

  • 编译时间慢

  • 缺乏依赖管理


我们来仔细研究一下。

节奏太慢


2017 年,我们迎来 C++17。虽然每三年就迎来一个新标准是很棒的,但许多开发人员抱怨新版本并不是每个人都期待的。


很多特性:比如概念(concept)、模块、范围(range)、协程(co-routine)……都没有被接受,我们至少需要再等三年才能让它们进入规范。


在 2020 年,C++20 已经准备就绪,并且这些重要特性将随编译器一起提供!但我们还是会抱怨合约(contract)还没加进来,反射(reflection)、执行器(executor)或网络(networking)仍在讨论中。它们可能出现在 C++23 甚至更高版本中。


看起来有些特性接受起来比较慢……而且总有东西值得抱怨。

节奏太快


像往常一样,我们在这里可能有两种相互矛盾的意见。尽管对某些人来说升级节奏很慢,但对其他人来说却很难跟上变化。


你刚刚学习了 C++11/14……现在你就需要更新 C++17 的知识,然后 C++20 就在路上了。三年并不是那么短的时间,但请记住,编译器一致性、公司政策、团队指南可能会以不同的节奏前进。


你的公司是立即更新到最新的 C++版本还是等待几年?

特性的混淆/复杂性


只需阅读这条评论:


CallMeDonk


我喜欢 C++。这是我的首选语言,但你必须承认,它对值类的“大杂烩”实现是很怪异的。包括我在内的大多数程序员更喜欢简单的、定义明确的语言结构,而不是奇怪和复杂的语法。


C++在各个方面都很清晰吗?可能不是……


以下是一些可能难以理解并可能让程序员糊涂的主题:

移动语义


移动语义的原则非常明确:不要复制,而是尝试“窃取”托管资源的内部结构,你应该获得不错的性能提升。但魔鬼都藏在细节中。


我不会写很多通用代码,所以幸运的是,我不必一直考虑移动语义。但是,当我遇到 move 和 const 时会很困惑——请参阅我上一篇关于该主题的文章。我不相信所有 C++开发人员都会理解这里的规则。特别是你现在需要记住编译器生成的六个默认操作:默认构造器、析构函数、复制构造器、移动构造器、赋值运算符和移动赋值运算符。

Rvalues/xvalues/prvalues……myValues、fooValues


最后一个是我编的……但那么多值类别实在太让人头疼了!


在 C(或 C++98/03)中,你只需要知道左值与右值,现在它有点微妙了。


不过,问题是你是否需要记住它?


一些不错的评论:


c0r3ntin


这很复杂,但不是每天都能遇到。这个值可以 address 吗?可以复制吗?可以移动吗?应该移动吗?只有在极少数情况下,你才需要主动去澄清并充分理解它们。(模板化库编写、热路径等)。大多数时候 C++并不比 java 或其他东西复杂。可悲的是大多数人都忘了这一点。C++可能是最复杂的语言,但是你可以编写非常好的代码而无需关心具体的细节。BigObject o=getBigObject();

初始化


现在有 18 种方式(从 C++17 开始)!


参阅:C++中的初始化是疯狂的r/cpp线程

模板(和模板推导)


当我看到 C++17 的所有变更时,我很迷茫;关于模板的细节太多了。


同样的情况发生在 C++20 中,我们迎来了一个重大且期待已久的改进:概念——它彻底改变了 C++。


然而,如果你想学习模板,一开始可能会不知所措。

ABI


随着新特性列表的不断增长,“从头开始”修复 C++设计中的旧问题可能是很诱人的主题。但这种语言的原则是不能破坏旧代码,所以委员会非常严格,不喜欢改变已引入特性的路线。


这个问题没有正确的答案,但无论如何,一个经过充分讨论的主题要比仓促的举动更好。

缺乏依赖管理工具


我们可以抱怨 C++没有“交​​付”一个很酷的依赖管理系统。但现实情况是,在可预见的未来,这可能都不会实现。拥有一个“标准”的包管理器是一个艰难的选择,尤其是它必须处理如此多的可用 C++的平台和系统。

不够安全


前段时间,你可以读到提到这个问题的一些文章(这篇这篇):


谷歌工程师本周表示,Chrome 代码库中大约 70%的严重安全漏洞是内存管理和安全漏洞。


微软也是如此。由于大部分代码是 C 或 C++,所以每个人都指责 C++不够安全。

其他问题?


你在这种语言上遇到的主要问题都有哪些?


到目前为止,我们已经讨论了一些问题……那么如何应对它们呢?有机会解决这些问题吗?

如何保持理智


没有完美的编程语言;每种语言都有一些问题。以下是我关于如何处理现代 C++问题的建议:


  • 保持乐观

  • 使用最佳指南

  • 使用最好的工具

  • 跟上最新进展

  • 不要打开引擎盖

  • 使用你需要的

  • 增量变更

  • 最后的底线:你的旧代码仍然安全并且可以编译

保持乐观,语言在不断发展


没有人愿意使用旧的语法和结构来编写代码。我们已经看到很多关于 C++11 之前的旧版 C++的抱怨。人们花了将近 13 年的时间(从主要的 C++98 算起,不包括次要的 C++03)才提出新的主要版本:C++11。现在我们可以很高兴回到了正轨,每三年都会有一些变化。归根结底,你不能说你的语言已经死了。


虽然某些特性非常庞大,可能会带来混乱或需要学习更多东西,但实际情况其实很简单:


  • 在 C++03 之后添加的 1000 个新页面中的大部分用于标准库。这意味着你可以使用更多助手和子系统,而无需查找第三方库。这绝对会让你的生活更轻松。

  • 对于移动语义,你可以依赖库类型,因为它们会为你完成正确的工作。例如,你现在可以安全地返回std::vector并确保它可能被移动甚至被删除,而无需额外副本。

  • 至于模板,它变得越来越容易使用。概念让代码更安全,没有像 SFINAE 这样的技巧。更重要的是,我们有了constexprauto,让泛型代码更简单了(几乎就像常规代码一样)。

  • 至于安全性:在这里查看 C++指南的安全配置文件的自动化工具。C++ Core Check中的新安全规则|C++团队博客。我们可以期待新的、更好的工具来执行代码分析甚至检测,以尽快发现潜在的安全问题。或者看这篇文章:使用静态分析原理缩小Rust和C++之间的差距——SunnyChatterjee——CppCon

使用指南


如果你对 C++代码的许多方面都感到困惑,那么你应该查阅 C++核心指南。它由热心的 C++开发社区创建,主要编辑是 Herb Sutter 和 Bjarne Stroustrup。


看这里:

C++核心指南@Github


这里有一个漂亮的网站:

C++核心指南:网站


只需输入你面临的问题(例如return value),你就可以轻松找到建议——例如:指南:返回值


使用这些指南将为你节省大量时间,并且你可以非常快地学习一些好的模式。

还有工具!


感谢 Clang 以及其他平台上的开发速度提升,我们获得了如下工具:



或者查看我关于其他工具的文章:C++生态系统:编译器、IDE、工具、测试等


虽然它不像其他语言(主要基于 Java 或基于.NET)那么好,但它正在变得越来越好。请记住,由于 C++语法复杂,因此很难实现即时分析代码的工具。

努力跟上最新进展


C++社区非常活跃。有很多博客、书籍、会议……甚至有可能在你所在的城市有本地社区。


首先,我建议去 isocpp.org 查看所有事件/新闻/文章。然后你可以查看Meeting C++和有关本地C++小组的信息。还有reddit/cpp,你可以在那里看到一些最棒的 C++故事。


还有CppCast——一个针对 C++开发人员的每周播客。


并参考以下书籍:



你还可以查看推荐的 C++资源列表:


Bartek的编程博客:资源

细节太多了?


C++如此强大的原因之一是它允许你实现非常接近底层的代码。你可以控制所有细节、内存布局、性能优化等……同时,这些能力增加了语言的复杂性。


不过,如果你不需要走那么远,你可以停留在相对较高的抽象级别。


例如,你不需要编写可选类型,因为你可以使用标准库中的std::optional。如果你不想涉及低级别和容易出错的联合类型,你应该意识到std::variant是一个安全的选项。

使用你需要的东西


C++是一种多范式语言;你可以以多种不同的方式使用它。最近,我读到了一条有趣的评论,说 Cpp 程序员在不接触模板元编程甚至异常等高级内容的情况下,也能持续多年表现出色。这在很大程度上取决于项目的代码风格。


例如,即使像谷歌这样的公司也限制了 C++的特性,比如说他们不使用异常


如果你不是库开发人员,你可能不会遇到自定义移动运算符或移动构造器的麻烦。同样,高级元编程的内容也可能不是你的代码的关键部分。

增量变更


如果你是从头开始或只有一个小的代码库,那么转到 C++11/14 应该相对容易一些。可是 20 年(或更久!)前开始创建的上百万行代码呢?


只需一步一步来就行了。


至少对于新代码,你应该开始使用现代 C++。此外,通过应用“童子军规则”,你可以改进你所接触的那些代码。


这可能会带来一些混合代码,但还是比只保留老旧风格要好。

最后的底线:你的旧代码仍然可以编译


C++规范越来越大的原因之一是该语言向后兼容。所以委员会通常会引入新特性,但很少删除旧的东西。所以……你的代码仍然可以编译。如果你不想前进,不想使用新的东西,那么你还是可以保持当前的风格。


有时你会收到一些关于不推荐使用的内容或删除特性的警告(如 C++17 中的auto_ptr),但即使在这种情况下,你也可以将编译器切换到一些较旧的 C++标准。

总结


这篇文章有一些抱怨,也有一些“美化”。我试图找出这种语言及其演变过程中存在的各种问题,以及一些积极的改进迹象。虽然我们可以抱怨复杂性、变化的速度等,但我认为我们不能说这种语言已经死掉了。这是好事!:)


我认为你不必快速追逐新特性并立即重写现有代码。试着跟上进展,使用真正改进你工作的特性,你的代码应该逐渐改进并变得更加“现代化”(这是可以定义的,请参阅 meetingcpp 的相关文章)。


  • 在采用 C++11/14/17/20 的新特性时,你的方法是什么?

  • 你使用 C++的主要问题是什么?

  • 你在工作中使用现代 C++吗?


原文链接:


https://www.cppstories.com/2017/02/how-to-stay-sane-with-modern-c/

2021-07-22 10:006752

评论 1 条评论

发布
用户头像
“不够安全” 这个问题解决不了的话比不过Rust的。
2021-07-22 13:40
回复
没有更多了
发现更多内容

企业im即时通讯工具推荐,企业内部即时通讯软件工具怎么选?

BeeWorks

TiDB 版本升级常见问题处理(v6.0 及以上版本)

TiDB 社区干货传送门

版本升级 故障排查/诊断

工程中实践的微服务设计模式

京东科技开发者

十分钟学会微调大语言模型

EquatorCoco

人工智能 自然语言处理 语言模型

Uniswap丨justswap丨pancakeswap去中心化薄饼交易所系统开发

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

数仓的两种轻量级数据交换格式:json与jsonb

华为云开发者联盟

数据库 华为云 华为云开发者联盟 华为云GaussDB(DWS) 企业号2024年4月PK榜

Topaz Gigapixel AI v7.1.1激活版 mac/win

iMac小白

【精选教程】四大网络抓包神器,总有一款适合你

雪奈椰子

BizDevOps全局建设思路:横向串联,纵向深化

嘉为蓝鲸

DevOps Dev Ops BizDevOps

TiDB 新特性解读 (6.0~6.6)

TiDB 社区干货传送门

管理与运维 版本测评 新版本/特性解读 6.x 实践 7.x 实践

记一次某节点没有Leader的问题分析

TiDB 社区干货传送门

实践案例 故障排查/诊断 7.x 实践

用了 18 个月时间,做 AI 应用从 0 到 200 万用户,从亏损到盈利(4000 字全面复盘)

陈宇明

创业 程序员 AI AI应用 AI创业

高清LED显示屏在舞台应用中的惊艳效果

Dylan

活动 高清视频 LED显示屏 全彩LED显示屏 led显示屏厂家

油猴Safari浏览器插件:Tampermonkey中文

iMac小白

加密货币交易所开发成本:2024 年完整指南

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

TiDB学习认证之路:数据库界的“快乐大本营”

TiDB 社区干货传送门

社区活动 学习&认证&课程

写给职场新人|从迷茫到屡获殊荣的技术人成长之路

京东科技开发者

云PBX的相关介绍

cts喜友科技

通信 通讯 云通讯

TiDB Vector抢先体验之用TiDB实现以图搜图

TiDB 社区干货传送门

数据库架构选型 新版本/特性解读 数据库前沿趋势

高效的 API 自动化测试

Liam

Jmeter 自动化测试 API测试 测试工具 API 自动化测试

数据治理的五大误区与破解方法

郑州埃文科技

数据治理

TiDB与MySQL在备份容灾体系的衡量对比

TiDB 社区干货传送门

管理与运维

AI从入门到入门之手写数字识别模型java方式Dense全连接神经网络实现

京东科技开发者

RocketMQ 存储机制浅析

字节跳动云原生计算

RocketMQ

Termius for Mac(多协议远程终端管理工具)

iMac小白

Termius下载 Termius for Mac下载 Termius for Mac破解

PTCP认真学习始(不是错别字,啊喂

TiDB 社区干货传送门

社区活动 学习&认证&课程

尝鲜 TiDB 企业管理器TEM 2.1.3 新版本

TiDB 社区干货传送门

监控

Kafka 线上性能调优

不在线第一只蜗牛

kafka 分布式

Optimism 黑客松大赛获奖名单公布

Footprint Analytics

AI gamefi Optimism

旅游电商的智能化升级:携程景点详情API引领新潮流

技术冰糖葫芦

API 接口 API 测试 pinduoduo API

C++实用指南_编程语言_Bartlomiej Filipek_InfoQ精选文章