写点什么

Herb Sutter 谈现代 C++ 本质

  • 2014-11-06
  • 本文字数:1621 字

    阅读完需:约 5 分钟

在 CppCon 2014 上,Herb Sutter 做了一个演讲,展示了现代 C++ 编程的基本惯用法。下面是一个简短的概要。

Herb 承认尽管 C++ 不是对每个程序员都是复杂的,但它是一个复杂的语言。Herb 建议这样来看待 C++,只有极少一部分程序员应该关注语言的最晦涩难懂的方面,比如当处理低层或库代码时,而其他人只需要通过默认的方式使用它,并让它能工作就可以了。

第一个例子是尽量多使用 range-for 循环。事实上,你也可以这样写:

复制代码
for (auto i = begin(c); i != end(c); ++i) { ... }

在现代 C++ 中,一个更容易的写法是这样的:

复制代码
for (auto& e : c) { ... }

这种写法也提供了更好的可读性。

指针、引用、new delete

Herb 的另一个强烈的建议是除非被封装在低层数据结构的实现内部,否则不要使用有所有权的指针(owning pointer)new 或者 delete。一个更好的选择是 unique_ptr,或者当你知道你需要共享这个对象的时候,使用 shared_ptr。因此,你可以很容易地写成:

复制代码
auto p = make_unique<widget>();
auto q = make_shared<widget>();

通过使用 make_unique 和 make_shared,你甚至不用担心 delete 的问题。

不管怎样,无所有权的指针(non-owning pointer)和引用仍然是一个很好的资源,并且使用它们最好的场合是传递参数给函数。Herb 认为使用任何种类的引用计数变量来传递参数是一种真正的反模式。这只可能导致性能问题,只有当你想把封装对象的所有权转移出去的时候才应该用它。

尽量多使用auto来声明局部变量

据 Herb 的说法,auto 关键字是现代 C++ 最大的特性之一。auto 能够用来推断类型,但是也可以用来指定类型并且一直代表那种类型。考虑下面的语句:

复制代码
auto i = v.begin();

这将正确地推断出所使用的类型。相比于下面的语句,这更简单并且不需要太多思考就能写出来。

复制代码
vector::const_iterator i = v.begin();

上面的语句专门需要思考使用 const_iterator。

正确性是 auto 的最大好处,但是它也有其他方面的好处:

· 可维护性:它使得代码自动适应变化,比如,函数的返回值。

· 性能:作为正确类型推断的必然结果,auto 能避免无意中产生临时对象,比如,初始化一个对象的时候。

· 可用性:在特殊的上下文中,比如,auto 是 lambda 函数的一个促成因素。

· 打字方便:它可以少敲几下键盘。

然而,有些情况下你不能使用 auto,换句话说,当你处理 C 数组或者不可移动的类型或者移动起来开销太大的类型,比如:

复制代码
auto lock = lock_guard<mutext> { m };  // 错误:不可移动
auto ai = atomic<int>{}; // 错误:不可移动
auto a = array<int,50>{}; // 正确,但开销太大

参数传递

Herb 演讲的很大一部分都专注在讨论参数传递。他的要点是,C++98 默认用法在现代 C++ 中还继续有效,并且代表了一个很好的起点,而右值优化带来更多的可能性。下面这个例子说明我们总是应该怎么做:

复制代码
class employee {
std::string name_;
public:
void set_name(const std::string& name) { name_ = name; } // 标准 C++98 的习惯
void set_name(std::string&& name) noexcept { name_ = std::move(name); } // 右值优化
};

另一方面,Herb 建议值传递主要用在构造函数中。在其他场合,当你按值传递一个命名参数(也即,非临时对象),并且允许右值优化,会引起很大的性能影响,因为该参数会被拷贝。

元组

Herb 最后一个建议是关于使用元组来返回多个值:

复制代码
tie(iter, success) = myset.insert("Hello");
if (success) do_something_with(iter);

除了强调默认用法和惯用法的重要性,Herb 也建议避免过度思考从而导致解决方案过度混淆。总之,他的秘诀是首先与语言提供的最基础的用法保持一致,然后通过实测,找到一些有希望改进的领域,尝试一些不一样的手段来改进性能。

查看英文原文: Herb Sutter on Modern C++ Essentials


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014-11-06 03:515626

评论

发布
暂无评论
发现更多内容

淘宝拍立淘接口全攻略:轻松实现图片搜索商品

tbapi

淘宝API 淘宝图片搜索接口 淘宝拍立淘接口

Python进行Socket接口测试的实现

我再BUG界嘎嘎乱杀

Python 编程 后端 socket 接口测试

豆瓣评分9.4!最适合Python入门后进阶的Python食谱!

我再BUG界嘎嘎乱杀

Python 编程 后端 开发语言

你敢在大学本科期间创办一家属于自己的公司吗?WTEAM 2024 年度大会,广州,9.10丨伙伴活动推荐

声网

第三期安全AI挑战者计划-文本分类对抗攻击 第十名「你钉起来真好听」技术总结

阿里云天池

聚道云软件连接器8月新增应用合集(3)

聚道云软件连接器

功能更新

释放生产力:JNPF低代码开发平台的五大优势

不在线第一只蜗牛

低代码 数字化

使用poetry来更优雅的管理 python 包

我再BUG界嘎嘎乱杀

Python 编程 后端 开发语言 Poetry

智扣物联,“论剑”长沙!2024全国大学生物联网竞赛火山引擎赛道获奖名单重磅揭晓

火山引擎边缘云

物联网 边缘计算 AIOT 智能IoT边缘服务 人工智能’

9k star 监控系统,100% 国产,推荐了解

秦晓辉

Prometheus Nightingale

Manulife IM发布自然资本、TCFD和SRI报告

财见

QCN9074, QCN9274, QCN9224 chip all-round analysis - leading the future of wireless networks

wifi6-yiyi

WiFi7

智能弹性实践:Kubernetes HPA 与观测云的自定义指标集成

观测云

k8s

2021全国数字生态创新大赛-智能算法赛季军方案 乘风破浪的炼丹师队

阿里云天池

关于 Git 的6大提示和技巧

秃头小帅oi

强强联手!媒体行业正式启用“算力包”模式算力服务!

九章云极DataCanvas

什么是算力?

九章云极DataCanvas

赛题解析 | 初赛赛道三:服务网格控制面分治体系构建

阿里云天池

云原生

袋鼠云产品功能更新报告11期|能力AI+,实力拿捏!

袋鼠云数栈

Match与RFG:颠覆传统社交,开启价值社交新时代

股市老人

【首席战略官分享】工作数字化的中国历程 | 从 OA 到 BPM 到数字流程自动化

望繁信科技

数字化转型 流程挖掘 流程智能

Web3 游戏周报(8.18 - 8.24)

Footprint Analytics

链游

ICEAI持续稳步发展,拓展全球市场交易版图

科技热闻

机器学习算法常用指标总结

阿里云天池

人社大赛算法赛题解题思路分享+第五名

阿里云天池

#大数据

AutoGPT理念与应用

霍格沃兹测试开发学社

Monorepo:让你的项目脱胎换骨,既能代码复用,又能独立部署!

OpenTiny社区

开源 前端 组件库 OpenTiny

“智启新机 云驱增长”——2024腾讯全球数字生态大会

ToB行业头条

心辰 Lingo 语音 AI 模型开放内测预约;Meta Sapiens 模型让 AI 分析图像中人类动作丨 RTE 开发者日报

声网

低代码革命:JNPF平台如何简化企业应用开发

EquatorCoco

低代码

如何实现持续、主动、长效的数据治理?主动元数据或是最佳答案

Aloudata

数据治理 元数据 全链路数据血缘 数据血缘 数据链路

Herb Sutter谈现代C++本质_C++_Sergio De Simone_InfoQ精选文章