《Imperfect C++中文版》——第1章 强制设计:约束、契约和断言

简介:

第1章 强制设计:约束、契约和断言

Imperfect C++中文版
在我们设计软件时,我们希望软件根据设计而进行使用。这并非一句空话。在大多数情况下,很容易发生以意料之外的方式来使用软件,而这么做的结果往往是令人失望的。

大多数软件的文档几乎都是不完整,甚至是过时的,我坚信你也有这方面的经验。这并非单纯的错误或缺失,“如果还有比没有文档更糟的情形,那就是文档是错误的”[Meye1997]。如果被使用的组件比较简单,使用得当,或者说是标准的或被普遍使用的,那么没有文档倒也不是什么大问题。例如,如果许多程序员需要一而再、再而三地查找C库函数malloc()的用法,那可真算是奇闻怪谈了。然而,这种情况毕竟很少。我曾经遇到一些程序员,他们非常有经验,但对malloc()的兄弟realloc()和free()之间的细微差别却并不那么熟悉。

对于这些问题,解决的方式很多。其一是通过增强的参数验证,使软件组件具有更强的抵抗错误的能力,但这种方式通常不那么有吸引力,因为它会损及性能,还倾向于滋生坏习惯。制作良好的文档并让它们保持更新当然是解决方案的一个重要组成部分,然而这种做法是远远不够的,因为它是“非强制性”的。此外,要想写出好文档也是一件极其困难的事情[Hunt2000]。软件越复杂,其原始作者要想把自己摆在对该软件懵懂无知的处境从而便于写出更好的说明文档就越不可能,而独立的技术作者要想抓住其所有的细微之处就更加困难了。因此,当情况不再单纯时,一个确保正确使用代码的更好的方式显然是必不可少的。

如果编译器能够为我们找出错误那就更可取了。事实上,本书中的相当一部分内容都是关于如何驱使和利用编译器,令它在碰到糟糕的代码时卡壳,从而便于我们在编译期及早抓住错误。但愿你能够意识到花几分钟来安抚编译器比花上几个小时和调试器纠缠要好得多。正如Kernighan和Pike在The Practice of Programming[Kenm1999]中所说的那样,“无论你喜欢与否,调试是一门我们经常要实践的艺术……如果不产生bug就好了,所以我们尝试在第一时间就把代码写正确,从而尽量避免bug的产生。”由于我并不比其他软件工程师更勤快,因此我总是尽量让编译器帮我做事情。从长远来看,“苦行僧”式的编程是比较容易的选择。然而,并非所有的错误都能够在编译期查出来。在这种情况下,我们需要求助于运行期机制。一些语言(例如D和Eiffel)提供了内建的机制,即通过“契约式设计(Design by Contract,Dbc)”来确保软件按照其设计而被使用。此项技术的先驱是Bertrand Meyer[Meye1997],它源于程序的形式验证。契约式设计要求为软件组件指定“契约”,这些契约会在程序运行过程中的某些特定点被强制执行。契约在很多方面都可以作为文档的替代品,因为它们无法被忽略,并且是自动进行验证的。此外,通过遵循特定的语法约定,它就可以和自动化文档工具合作,我们将会在1.3节对此进行讨论。

实施“强制(enforcement)”的机制之一是断言(assertion),包括广为人知的运行期断言,以及较少为人知然而甚至更为有用的编译期断言。本书中两者均得到了大量的使用,因此我们将会在1.4节对这种重要的工具进行详细的观察。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

相关文章
|
编译器 API C++
c++ 新特性 概念和约束 “无规矩 难成方圆”
c++ 新特性 概念和约束 “无规矩 难成方圆”
124 1
|
11月前
|
C++
C++ Primer Plus (第6版)中文版 (使用XMind整理)
C++ Primer Plus (第6版)中文版 (使用XMind整理)
C++ Primer Plus (第6版)中文版 (使用XMind整理)
|
10月前
|
C++ 开发者
C++一分钟之-概念(concepts):C++20的类型约束
【7月更文挑战第4天】C++20引入了Concepts,提升模板编程的类型约束和可读性。概念定义了模板参数需遵循的规则。常见问题包括过度约束、约束不完整和重载决议复杂性。避免问题的关键在于适度约束、全面覆盖约束条件和理解重载决议。示例展示了如何用Concepts限制模板函数接受的类型。概念将增强模板的安全性和灵活性,但需谨慎使用以防止错误。随着C++的发展,Concepts将成为必备工具。
211 2
|
10月前
|
C++ 开发者
C++一分钟之-概念(concepts):C++20的类型约束
【7月更文挑战第6天】C++20引入了Concepts,提升模板编程的精确性和可读性。概念允许设定模板参数的编译时约束。常见问题包括过度约束、不完整约束及重载决议复杂性。要避免这些问题,需适度约束、全面覆盖约束条件并理解重载决议。示例展示了如何定义和使用`Incrementable`概念约束函数模板。概念是C++模板编程的强大力量,但也需谨慎使用以优化效率和代码质量。
186 0
|
11月前
|
算法 程序员 编译器
C++一分钟之概念(concepts):C++20的类型约束
【6月更文挑战第30天】C++20的Concepts革新了模板编程,允许更清晰地表达类型要求,提升代码可读性和编译错误反馈。本文探讨Concepts基础、应用场景、易错点及避免策略,展示如何通过概念定义如Iterable、Addable,创建更健壮的泛型代码,强调了理解和利用编译器错误信息的重要性,以及概念与类型别名的区别。Concepts现已成为现代C++程序员的关键技能。
294 0
|
存储 Java 应用服务中间件
线程池设计, 从简单的我们平常设计线程池图解,到生活中的类似线程池的处理现实场景, 到简单的C++模拟nginx写的单链表组织工作队列的简单线程池实现 + nginx 部分源码刨析
线程池设计, 从简单的我们平常设计线程池图解,到生活中的类似线程池的处理现实场景, 到简单的C++模拟nginx写的单链表组织工作队列的简单线程池实现 + nginx 部分源码刨析
线程池设计, 从简单的我们平常设计线程池图解,到生活中的类似线程池的处理现实场景, 到简单的C++模拟nginx写的单链表组织工作队列的简单线程池实现 + nginx 部分源码刨析
|
架构师 数据挖掘 程序员
C++ 类设计和实现的十大最佳实践
C++ 类设计和实现的十大最佳实践
983 0
C++ 类设计和实现的十大最佳实践
|
设计模式 测试技术 uml
[学习][笔记]设计模式(基于C/C++实现)之 设计基础
设计模式(基于C/C++实现)之 设计基础
408 0
[学习][笔记]设计模式(基于C/C++实现)之 设计基础
C++编程练习:多态实验——设计一个基类Shapes,Shapes类公有派生产生矩形类Rectangle和圆类Circle
C++编程练习:多态实验——设计一个基类Shapes,Shapes类公有派生产生矩形类Rectangle和圆类Circle
C++编程练习:多态实验——设计一个基类Shapes,Shapes类公有派生产生矩形类Rectangle和圆类Circle
C++编程练习:设计一个银行账户类,包含户名、帐号以及当前余额属性,并且能完成开户、存款、取款和查询余额等行为。
C++编程练习:设计一个银行账户类,包含户名、帐号以及当前余额属性,并且能完成开户、存款、取款和查询余额等行为。
C++编程练习:设计一个银行账户类,包含户名、帐号以及当前余额属性,并且能完成开户、存款、取款和查询余额等行为。