1.4 C++特性一览

接下来,我们会一窥C++11中的各种特性,了解它们的来历、用途、特色等。可能这部分对于还没有开始阅读正文的读者来说有些困难。如果有机会,我们建议读者在读完全书后再回到这里,这也是全书最好的总结。

1.4.1 稳定性与兼容性之间的抉择

通常在语言设计中,不破坏现有的用户代码和增加新的能力,这二者是需要同时兼顾的。就像之前的C一样,如今C++在各种代码中、开源库中,或用户的硬盘中都拥有上亿行代码,那么当C++标准委员会要改变一个关键字的意义,或者发明一个新的关键字时,原有代码就很可能发生问题。因为有些代码可能已经把要加入的这个准关键字用作了变量或函数的名字。

语言的设计者或许能够完全不考虑兼容性,但说实话这是个丑陋的做法,因为来自习惯的力量总是超乎人的想象。因此C++11只是在非常必要的情况下才引入新的关键字。WG21在加入这些关键字的时候非常谨慎,至少从谷歌代码搜索(Google Code Search)的结果看来,这些关键字没有被现有的开源代码频繁地使用。不过谷歌代码搜索只会搜索开源代码,私人的或者企业的代码库(codebase)是不包含在内的。因此这些数据可能还有一定的局限性,不过至少这种方法可以避免一些问题。而WG21中也有很多企业代表,他们也会帮助WG21确定这些关键字是否会导致自己企业代码库中代码不兼容的问题。

C++11的新关键字如下:

❑alignas

❑alignof decltype

❑auto(重新定义)

❑static_assert

❑using(重新定义)

❑noexcept

❑export(弃用,不过未来可能留作他用)

❑nullptr

❑constexpr

❑thread_local

这些新关键字都是相对于C++98/03来说的。当然,引入它们可能会破坏一些C++98/03代码,甚至更为糟糕的是,可能会悄悄地改变了原有C++98/03程序的目的。static_assert就是这样一个例子。为了降低它与已有程序变量冲突的可能性,WG21将这个关键字的名字设计得很长,甚至还包含了下划线,可以说命名丑得不能再丑了,不过在一些情况下,它还是会发生冲突,比如:


static_assert(4<=sizeof(int),"error:small ints");


这行代码的意图是确定编译时(不是运行时)系统的int整型的长度不小于4字节,如果小于,编译器则会报错说系统的整型太小了。在C++11中这是一段有效的代码,在C++98/03中也可能是有效的,因为程序员可能已经定义了一个名为static_assert的函数,以用于判断运行时的int整型大小是否不小于4。显然这与C++11中的static_assert完全不同。

实际上,在C++11中还有两个具有特殊含义的新标识符:override、final。这两个标识符如何被编译器解释与它们所在的位置有关。如果这两个标识符出现在成员函数之后,它们的作用是标注一个成员函数是否可以被重载。不过读者实际上也可以在C++11代码中定义出override、final这样名称的变量。而在这样的情况下,它们只是标识了普通的变量名称而已。

我们主要会在第2章中看到相关的特性的描述。