第一章 抽象 将公共的抽象提取出来放到基类中。 一个类应该能够描述一组对象。 如果派生类之间的区别在于属性,则用数据成员来表示;如果在于行为,则用虚函数来表示。 如果通过共有继承来产生派生类,那么这个派生类应该是其基类的特化。 多态性并不是所有程序设计问题的解决方案 第二章 一致性 构造函数应该使得对象处于定义明确的状态。 我们应该考虑使用默认参数的形式来代替函数重载的形式。 用一致的方式来定义对象的状态——这需要识别出类不变性。 类的接口定义应该是一致的——避免产生困惑。 对于每个new操作,都有相应的delete操作。 避免对从不使用的状态信息进行计算和储存。 在定义operator=时,我们要注意x=x这种情况。 用一个通用的函数来代替重复的表达式序列。 第三章 不必要的继承 我们要找出简单的抽象。 我们要识别出队实现的继承;可以使用私有基类或者(更好的办法是)使用成员对象。 我们应该考虑使用默认参数的形式来代替函数重载的形式。 第四章虚函数 派生类在处理继承而来的状态时必须与基类保持一致。 如果在共有基类中没有定义虚析构函数,那么在所有的派生类或者派生类的数据成员中都应该没有定义析构函数。 通常情况下,共有基类的析构函数应该被声明为虚函数。 将共同的行为迁移到基类中。 降低耦合性——将类之间的交互最小化。 如果派生类之间的区别在于属性,则用数据成员来表示;如果在于行为,则用虚函数来表示。 没有哪个类是完美的;过窄的设计要好于过宽的设计。 第五章 运算符的重载 我们应该编写出清晰的程序——而不是为了展示自己聪明的程序。 重载运算符的含义必须是自然的,而不是为了展示程序员的聪明。 重载运算符必须能够与其他的运算符进行正确的交互。 我们要保持重载运算符的行为是一致的。 我们喜爱重载运算符时,应该保持一组相关运算符的完整性。 在定义operator=时,我们要注意x=x这种特殊情况。 在对运算符进行重载时,我们要避免使其他的程序员产生困惑。 我们要识别出对实现的继承;可以使用私有基类或者(更好的方法是)使用成员对象。 第六章 包装 我们需要知道从函数中返回的指针的有效生存期。 独立的对象应该有独立的行为。 不要对某些基本的信息进行完全的封装——我们要使得这些信息可以通过某些方法来进行访问。 在发生错误时,对象的行为应该是明确定义的。 我们要使得C++包装类能够改善C接口。 第七章 效率 降低耦合性——将类之间的交互最小化。 我们不能只通过主观臆测就做出判断, 而是应该通过执行性能分析的结果来找出问题所在。 我们需要对类的实现进行分析,以找出性能问题的根源。 我们也可以通过分析客户代码来找出性能问题的根源。 完整的接口将有助于实现搞笑的客户代码。 我们要找出简单的抽象。 第八章 案例研究 我们要始终记住结束空字符串的存在——正确的表达式应该是new char[strlen(s)+1]。 不要使用构造函数来初始化静态数据成员。 降低耦合性——将类之间的交互最小化。 每个类都应该只有唯一的、内聚的功能。 我们应该将类设计成抽象数据类型而不是模块类。 如果派生类之间的区别在于属性,则用数据成员来表示;如果在于行为,则用虚函数来表示。 如果泛化的情形同样简单时,那么我们最好不要只实现某种具体的情形。 通常情况下,共有基类的析构函数应该被声明为虚函数。 第九章 多重继承 在使用虚基类之前,我们需要彻底地理解它们。 不要试图从你正在使用的编译器中来学习多重继承的语义。 我们要避免人为地将一个类限制为只能被用作基类。 如果在共有基类中没有定义虚析构函数,那么在所有的派生类或者派生类的数据成员中都应该没有定义析构函数。 如果在多重继承的层次结构中存在着析构函数, 那么每个基类的析构函数都应该是虚函数。 如果在客户对象中需要包含某种服务,那么我们应该使用成员对象,而不是继承。 一个类应该能够描述一组对象。