C++之父谈C++语言设计规则( 五 )


C++之父谈C++语言设计规则文章插图
支持健全的设计概念:任何个别的语言特征都必须符合一个整体模式 , 这个整体模式必须能帮助回答一个问题——什么样的功能是我们需要的 。 语言本身不可能提供这种东西 , 这个指导模式必然来自另一个完全不同的概念层次 。 对C++ 而言 , 这个概念层次就是有关程序应该如何设计的基本思想 。
我的目标是提升系统程序设计中的抽象层次 , 其方式类似于C语言在取代汇编语言作为系统工作主流时的所作所为 。 有关新特征的想法都放在这一统一框架中考虑 , 看它们在将C++ 提升为一种表述设计的语言时能起到什么作用 。 特别是对个别特征的考虑 , 就要看它能否形成一种可以通过类进行有效表述的概念 。 对于C++ 支持数据抽象和面向对象的程序设计 , 这是最关键的问题 。
一个程序设计语言不是也不应该是一个完整的设计语言 。 因为设计语言应该更丰富 , 不必像适合做系统程序设计的语言那样过多地关心细节 。 但是 , 程序设计语言也应该尽可能直接地支持某些设计概念 , 以使设计师和程序员(这些人常常是“戴着不同帽子的”同一批人)之间更容易沟通 , 并能简化工具的构造 。
采用设计的术语来观察程序设计语言 , 更容易基于该语言与其支持的设计风格之间的关系 , 去考虑接受或者拒绝人们建议的语言特征 。 没有一种语言能支持所有风格 , 而如果一个语言只支持某种定义狭隘的设计哲学 , 它也将因为缺乏适应性而失败 。 提升C++ 语言使之支持宽谱的设计技术 , 将它们映射到“更好的”C / 数据抽象 / 面向对象程序设计 , 使我们能在为发展提供持续动力的同时 , 避免把C++ 弄成所有人的唯一工具 。
为程序的组织提供丰富的机制:与C语言相比 , C++ 能帮助人们更好地组织程序 , 使之更容易书写、阅读和维护 。 我把计算看成已经由C语言解决的问题 。 和几乎所有人一样 , 我也有一些关于C表达式和语句应如何改进的想法 。 但我决定把自己的努力集中到其他方面 。 有关表达式或语句的新建议 , 都需要仔细评价 , 看它是能影响程序的结构呢 , 还是仅使表达某种局部计算变得更容易些 。 除了不多的例外 , 例如允许声明出现在第一次需要变量的位置(3.11.5节)等 , C语言的表达式和语句结构都保持不变 。
直接说出你的意思:低级语言有一个最本质的问题 , 那就是在人们互相交流时能如何表述问题 , 和他们在使用程序设计语言时能如何表述问题之间存在一条鸿沟 。 程序的基本结构常常被淹没在二进制位、字节、指针和循环等的泥潭中 。
要缩小这种语义鸿沟 , 最基本的方法就是使语言更具有说明性 。 C++ 语言提供的每种机制都与使某种东西更具有说明性相关 , 然后是为了一致性检查、检测出愚蠢的错误 , 或者改进所生成的代码而开发的一些附加结构 。
在无法使用说明性结构的地方 , 某种更明确的记法常常会有所帮助 。 分配/释放运算符(10.2节)和新的强制转换记法(14.3节)都是很好的例子 。 有关直接而明显地表达意图的思想 , 很早就有一种说法:“允许用语言本身表达所有重要的东西 , 而不是在注释里或者通过宏这类黑客手段 。 ”这也意味着 , 一般而言 , 这个语言必须具有比原来的通用语言更强的表达能力和灵活性 , 特别是它的类型系统 。
所有特征都必须是能够负担的:仅仅给用户提供一种语言特征 , 或者针对某个问题建议一种技术还不够 。 提供的解决方案还必须是能负担得起的 , 否则这个建议简直就是一种侮辱 , 就像对于提问“什么是到孟菲斯的最好方式” , 你回答说“去租一架专机”一样 。 对不是百万富翁的人们而言 , 这绝不是一个有益的回答 。
只有在无法找到其他方法 , 而且能在付出明显更低的代价并得到类似效果时 , 才应该把这个特征加进C++ 。 我自己的经验是 , 如果程序员可以在高效地或优雅地做某种事情之间做选择 , 大部分人将选择效率 , 除非存在其他更重要更明显的原因 。 例如 , 提供inline函数是为了无代价地跨过保护边界 , 对于宏的许多使用而言 , 这都是另一种具有更好行为的选择 。 这里的思想是显然的:一种功能应该同时是优雅的而又是高效的 。 在无法同时达到这些的地方 , 或者不提供这种功能 , 或者是——如果要求非常迫切——高效地提供它 。