脱胎换骨的现代C++11有哪些出奇的新特性?

从C++11开始,我们都称之为现代C++。现代C++的新特性皆围绕C++之父Bjarne指明的两条主线:一是直接硬件映射,二是零开销抽象。这也正好体现了C++的蜕变方向:更快、更好用。

从C++98到现代C++

要聊现代C++,还得从C++的发展历程说起:

1998年,C++标准委员会发布了C++语言的第一个国际标准,也就是我们现在使用的最多的C++98;

2003年,标准委员会针对98版本中存在的诸多问题进行了修订,修订后发布了C++03;

2005年,C++标准委员会发布了一份技术报告,详细说明了引入C++新特性的计划。因为当时预计会在本世纪第一个十年的某个时间发布,这个新标准被非正式地命名为C++0x。但是,这个标准最终在2011年才面世,也就是C++11,此次标准为C++98发布后13年来的第一次重大修正;

2014年,标准委员会公布了C++14标准;

2017年,标准委员会计划即将公布的C++17标准。

从C++11开始,我们都称之为现代C++。在C++通过演变来发展其定义的过程中,偶尔引发过与现有代码的兼容问题。不过根据Bjarne Stroustrup表示,新的标准将几乎100%兼容于现有标准。

图0:脱胎换骨的现代C++11有哪些出奇的新特性?

从上图中我们可以看出,现代C++引入了很多的新特性,如智能指针、lambda表达式、auto类型推导、右值引用和move移动语义等等。所有这些新特性都体现了C++的发展方向:更快、更好用。

更好用,不是梦

智能指针

“智能指针”使我们不用再担心内存管理的问题。对于C/C++程序员来说,指针是天堂,同时指针也是地狱。指针有很多好处,也有很多让人头疼的问题:野指针、内存泄露等等。在C++11中,引入了如下三种智能指针:unique_ptr、shared_ptr和weak_ptr。这3种指针组件就是采用了boost里的智能指针方案,C++11将boost里的这一套纳入了标准。

图1:脱胎换骨的现代C++11有哪些出奇的新特性?

lambda表达式

“lambda表达式”让我们的算法更加清晰。C++11添加了一项名为lambda表达式的新功能,通过这项功能可以编写内嵌的匿名函数,而不必编写独立函数和函数对象,使得代码更容易理解。

类型推导

“类型推导”不仅让我们写代码更加简洁还让推断模板函数的返回类型更加便利。C++11中引入auto 和 decltype这两个关键字,auto能让编译器替我们去分析表达式所属的类型,decltype的作用是选择并返回操作数的数据类型。如:

图2:脱胎换骨的现代C++11有哪些出奇的新特性?

这样使用最明显的好处就是在使用迭代器遍历STL容器的时候,不用去声明那些迭代器的类型,也不用去使用typedef就能很简洁的实现遍历了。从效率上来说,auto不会对运行时效率产生影响,它是在编译的时候推导类型的,例如上面的代码,编译的时候,就会把num变量转换为int类型。

有的时候我们还会遇到这种情况,我们希望从表达式中推断出要定义变量的类型,但却不想用表达式的值去初始化变量。还有可能是函数的返回类型为某表达式的值类型。在这些时候auto显得就无力了,所以C++11又引入了第二种类型说明符decltype,它的作用是选择并返回操作数的数据类型。在此过程中,编译器只是分析表达式并得到它的类型,却不进行实际的计算表达式的值。

图3:脱胎换骨的现代C++11有哪些出奇的新特性?

在这里编译器并不实际调用f函数,而是分析f函数的返回值作为sum的定义类型。

基于范围的for循环

“基于范围的for循环”使得按顺序访问其中的每个元素变得非常方便。

图4:脱胎换骨的现代C++11有哪些出奇的新特性?

更快速,通大路

线程库

“线程库”让我们能方便地编写出可移植的并发程序,并且创建和启动一个C++线程变得非常简便。

图5:脱胎换骨的现代C++11有哪些出奇的新特性?

右值引用和转移语义

“右值引用和转移语义”可以避免无谓的拷贝,节省运算存储资源,提高效率和程序性能。

C++11增加一个新的非常数引用(reference)类型,称作右值引用(R-value reference),标记为T &&。右值引用所引用的临时对象可以在该临时对象被初始化之后做修改。右值引用是用来支持转移语义的。转移语义可以将资源 ( 堆,系统对象等 ) 从一个对象转移到另一个对象,这样能够减少不必要的临时对象的创建、拷贝以及销毁,能够大幅度提高 C++ 应用程序的性能。临时对象的维护 ( 创建和销毁 ) 对性能有严重影响。转移语义是和拷贝语义相对的,可以类比文件的剪切与拷贝,当我们将文件从一个目录拷贝到另一个目录时,速度比剪切慢很多。通过转移语义,临时对象中的资源能够转移其它的对象里。

原子类型

“原子类型”可以让我们线程间的数据共享更加方便、安全。

我们知道原子操作就是多线程程序中“最小的且不可并行化的”的操作。通常情况下,原子操作都是通过“互斥”的访问来保证的,如借助POSIX标准的pthread库中的互斥锁mutex可以做到。

在新标准C++11,引入多种原子操作数据类型,例如,atomic_bool,atomic_int等等,如果我们在多个线程中对这些类型的共享资源进行操作,编译器将保证这些操作都是原子性的,也就是说,确保任意时刻只有一个线程对这个资源进行访问,编译器将保证,多个线程访问这个共享资源的正确性。从而避免了锁的使用,提高了效率。

如何创造更好的C++未来

C++11相比C++98来说已经有了脱胎换骨的变化,随着已经面世的C++14和即将到来的C++17,C++将充满活力地持续发展。随着C++新标准的不断发展,越来越多的现代编程语言的特性将会被引入,C++将越来越受欢迎。

在Windows下,我们常用的Visual Studio 2012已经支持大部分C++11的特性。而在Linux 下,升级GCC到4.8及以上也可使用C++11的特性。更好的C++未来并非遥不可及,只要你愿意从身边开始发现和创造。

加载余下内容▼

相关文章:

;