More Effective C++ 简体中文版(pdf 版)
### More Effective C++ 简体中文版(pdf 版) #### 译序与导读 本书由著名作家Scott Meyers撰写,译者为中国台湾的侯捷先生。此书被誉为C++程序员必读的经典之作,共包含30条针对C++编程的实用建议。 #### 本书所谈的C++ 书中首先介绍了C++作为一种面向对象的编程语言,其复杂性不仅体现在语法层面,更在于其背后所蕴含的深层次思想和设计模式。C++支持多种编程范式,包括过程式编程、面向对象编程、泛型编程等,这使得C++既强大又灵活,但也因此增加了学习难度。 #### 惯例与术语 本书中使用了一系列专业术语,并且为了便于读者理解和应用,作者特别指出了书中的一些特定术语和约定,例如对于特定概念的命名方式、代码示例中的注释风格等。 #### 臭虫报告,意见提供,内容更新 作者鼓励读者发现书中的错误或不准确之处时能够及时反馈,以便于后续版本的改进和完善。 #### 基础议题 - **Item 1:指针与引用的区别** 在C++中,指针和引用都是用于表示对象地址的方式,但它们之间存在显著区别。指针可以被重新赋值以指向不同的对象,而引用则在初始化后无法改变其所绑定的对象。此外,指针可以通过`NULL`进行初始化,表示它不指向任何对象;而引用必须始终绑定到一个对象上。理解这些区别有助于编写更加安全可靠的代码。 - **Item 2:尽量使用C++风格的类型转换** 传统上,C语言中的类型转换通常采用 `(type)` 的形式,但在C++中,这种方式可能导致一些意外的结果。因此,作者建议尽可能使用C++风格的类型转换,如 `static_cast<T>()`、`const_cast<T>()`、`reinterpret_cast<T>()` 和 `dynamic_cast<T>()`。这些类型转换提供了更清晰的意图表达,并有助于编译器检测潜在的错误。 - **Item 3:不要对数组使用多态** 多态性是C++面向对象编程的一个重要特性,但当涉及到数组时,则应避免使用多态。这是因为数组在C++中会被退化为指针,从而导致某些多态行为失效。为了避免这种问题,可以使用STL容器如 `std::vector` 或 `std::array` 来替代原始数组。 - **Item 4:避免无用的缺省构造函数** 缺省构造函数如果不需要,则不应声明。这不仅可以减少编译时间,还能避免不必要的混淆。当类中有成员变量需要初始化时,应当显式地提供构造函数以确保正确初始化。 #### 运算符 - **Item 5:谨慎定义类型转换函数** 类型转换函数是C++中用于实现用户定义类型的隐式或显式转换的关键。然而,不当的使用可能会导致难以调试的问题。因此,作者建议在定义类型转换函数时要格外小心,并确保它们的行为符合预期。 - **Item 6:自增(INCREMENT)、自减(DECREMENT)操作符前缀形式与后缀形式的区别** 自增和自减操作符有两种形式:前缀形式 (`++x`) 和后缀形式 (`x++`)。前缀形式先增加(或减少)后使用新值,而后缀形式则是先使用旧值再进行增加(或减少)。了解这些差异有助于编写更高效、更易于理解的代码。 - **Item 7:不要重载“&&”, “||”, 或 “,”** 这些运算符在C++中有特殊的语义,重载它们可能会导致代码难以理解和维护。作者建议避免对这些运算符进行重载,以保持代码的一致性和可读性。 - **Item 8:理解各种不同含义的NEW和DELETE** `new` 和 `delete` 是C++中用于动态内存分配的关键字。了解它们的不同形式及其含义对于避免内存泄漏至关重要。例如,`new[]` 和 `delete[]` 用于数组的动态分配和释放,而普通的 `new` 和 `delete` 适用于单个对象的分配和释放。 #### 异常 - **Item 9:使用析构函数防止资源泄漏** 析构函数是在对象生命周期结束时自动调用的函数,可用于释放资源。通过在析构函数中执行清理操作,可以有效地避免资源泄漏。 - **Item 10:在构造函数中防止资源泄漏** 当对象创建失败时,可能会留下未释放的资源。通过使用所谓的“资源获取即初始化”(RAII)技术,可以在构造函数中确保所有资源都被正确管理,即使发生异常也能自动释放。 - **Item 11:禁止异常信息(EXCEPTIONS)传递到析构函数外** 如果在析构函数中抛出异常,可能会导致不可预测的行为。因此,应确保析构函数不会抛出异常,或者在必要时采取特殊措施来处理这种情况。 - **Item 12:理解“抛出一个异常”与“传递一个参数”或“调用一个虚函数”间的差异** 抛出异常是一种控制流程转移的手段,与传递参数或调用虚函数不同。理解这些操作之间的区别对于编写健壮的代码至关重要。 - **Item 13:通过引用(REFERENCE)捕获异常** 使用引用捕获异常可以避免不必要的复制,并提高代码的性能。同时,这也使得异常处理代码更加简洁明了。 - **Item 14:审慎使用异常规格(EXCEPTION SPECIFICATIONS)** 异常规格在C++中用于指定函数可能抛出的异常类型。虽然这在一定程度上可以帮助编译器进行优化,但过度依赖异常规格可能会导致代码变得复杂且难以维护。因此,在实际编程中应当谨慎使用。 - **Item 15:了解异常处理的系统开销** 异常处理机制在运行时会产生一定的开销。理解这些开销可以帮助开发者做出更好的设计决策,尤其是在性能敏感的应用场景中。 #### 效率 - **Item 16:牢记80-20准则(80-20 RULE)** 80-20法则指出,通常情况下20%的代码消耗了80%的计算资源。因此,在优化代码时应当重点关注那些关键部分,而不是试图全面优化每一行代码。 - **Item 17:考虑使用LAZY EVALUATION(懒惰计算法)** 懒惰计算是指仅在真正需要时才进行计算的一种策略。通过推迟计算,可以减少不必要的工作量,从而提高整体性能。 - **Item 18:分期摊还期望的计算** 分期摊还是一种在多个操作中平均分配成本的方法,它可以避免某些操作的成本过高,从而使整个系统的性能更加均衡。 - **Item 19:理解临时对象的来源** 临时对象是在某些操作中自动生成的对象,例如函数返回值或表达式的中间结果。了解何时何地会产生临时对象有助于避免不必要的资源浪费。 - **Item 20:协助完成返回值优化** 返回值优化(RVO)是编译器优化技术之一,用于减少构造临时对象的成本。通过合理的设计,可以更好地利用这一优化,从而提高代码效率。 - **Item 21:通过重载避免隐式类型转换** 隐式类型转换有时会导致意外的结果。通过重载运算符或提供显式转换函数,可以更明确地控制类型转换的过程,从而提高代码的安全性。 - **Item 22:考虑用运算符的赋值形式(OP=)取代其单独形式(OP)** 对于某些操作符,使用赋值形式(如 `+=`)可以比单独的形式(如 `+`)更高效。这是因为赋值形式通常会尝试在原地修改对象,从而避免不必要的复制。 - **Item 23:考虑变更程序库** 不同的程序库可能在性能方面存在显著差异。在选择合适的库时,应当综合考虑功能需求、性能表现和维护情况等多个因素。 - **Item 24:理解虚拟函数、多继承、虚基类和RTTI所需的代价** 虚拟函数、多继承和虚基类等特性虽然提供了强大的功能,但也带来了额外的运行时开销。了解这些特性的具体实现细节可以帮助开发者做出更为明智的设计决策。 #### 技巧(TECHNIQUES,又称IDIOMS或PATTERN) - **Item 25:将构造函数和非成员函数虚拟化** 将构造函数和非成员函数声明为虚拟函数可以使子类更好地覆盖父类的行为。然而,这种做法并不常见,因为构造函数本身不能被直接调用。在某些情况下,可以使用工厂方法或模板技术来达到类似的效果。 - **Item 26:限制某个类所能产生的对象数量** 通过限制一个类可以创建的对象数量,可以实现资源的有效管理和保护。这种技术通常用于实现单例模式或有限数量的资源池。 - **Item 27:要求或禁止在堆中产生对象** 通过使用特定的设计模式或编程技术,可以控制对象是否应该在堆上分配。这对于避免内存碎片和提高程序性能非常有用。 - **Item 28:灵巧(SMART)指针** SMART指针是一系列自动管理内存的指针类型,如 `std::unique_ptr`、`std::shared_ptr` 和 `std::weak_ptr`。它们可以自动释放不再使用的内存,从而避免常见的内存泄漏问题。 - **Item 29:引用计数** 引用计数是SMART指针内部使用的一种机制,用于跟踪指向同一对象的指针的数量。当引用计数降至零时,对象会被自动销毁。了解引用计数的工作原理有助于编写更高效、更安全的代码。 - **Item 30:代理类** 代理类是一种设计模式,用于代表另一个对象并提供额外的功能,如缓存、权限检查等。了解代理类的用途和实现可以帮助开发者解决复杂的问题。 - **Item 31:让函数根据一个以上的对象来决定怎么虚拟** 通过让函数基于多个对象的状态来决定其行为,可以实现更加灵活和高效的多态性。这种技术通常用于实现更高级别的抽象。 #### 杂项 - **Item 32:在未来时态下开发程序** 在设计软件时,应当考虑到未来可能出现的需求变化和技术进步。通过采用灵活的设计模式和技术,可以使软件更容易适应未来的变革。 - **Item 33:将非尾端类设计为抽象类** 抽象类是一种包含至少一个纯虚函数的类,它不能被实例化。通过将非尾端类设计为抽象类,可以确保这些类只能作为其他类的基础,并强制子类实现特定的行为。 - **Item 34:如何在同一程序中混合使用C++和C** 在某些情况下,可能需要在一个项目中同时使用C++和C代码。了解如何正确地混合这两种语言可以帮助避免常见的兼容性问题。 - **Item 35:让自己习惯使用标准C++语言** C++标准库提供了丰富的工具和功能,可以大大简化开发过程。通过熟悉和使用这些标准库组件,可以编写更加高效、可靠和易于维护的代码。 ### 结论 《More Effective C++》这本书为C++程序员提供了宝贵的指导,涵盖了从基础知识到高级主题的广泛内容。通过遵循书中的建议,开发者可以编写出更高质量、更安全和更高效的C++代码。无论是初学者还是经验丰富的专业人士,都能从中获得有价值的见解和灵感。
- 粉丝: 0
- 资源: 2
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助