Herb Sutter谈现代C++本质

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

\\

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

\\

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

\\
\for (auto i = begin(c); i != end(c); ++i) { ... }
\\

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

\\
\for (auto\u0026amp; e : c) { ... }
\\

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

\\

指针、引用、new delete

\\

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

\\
\auto p = make_unique\u0026lt;widget\u0026gt;();\auto q = make_shared\u0026lt;widget\u0026gt;();
\\

通过使用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\u0026lt;mutext\u0026gt; { m };  // 错误:不可移动\auto ai = atomic\u0026lt;int\u0026gt;{}; // 错误:不可移动\auto a = array\u0026lt;int,50\u0026gt;{}; // 正确,但开销太大
\\

参数传递

\\

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

\\
\class employee {\   std::string name_;\public:\    void set_name(const std::string\u0026amp; name) { name_ = name; }    // 标准 C++98 的习惯\    void set_name(std::string\u0026amp;\u0026amp; 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)关注我们,并与我们的编辑和其他读者朋友交流。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值