Effective C++编程指南

需积分: 0 0 下载量 105 浏览量 更新于2024-07-31 收藏 1.39MB PDF 举报
"effective.pdf" 《Effective C++》是Scott Meyers的经典著作,书中列举了一系列针对C++编程的最佳实践和常见陷阱。以下是对书中的部分关键知识点的详细解释: 1. **尽量用`const`和`inline`而不用`#define`**:`const`提供了类型安全,可以用于常量表达式,编译器可以进行更多优化;`inline`用于减少函数调用开销,但不保证总是被内联。`#define`预处理器宏则缺乏类型检查,可能导致难以预料的副作用。 2. **尽量用`<iostream>`而不用`<stdio.h>`**:C++标准库使用`iostream`提供面向对象的输入/输出,更符合C++编程风格,且支持流控制和异常处理。`stdio.h`是C库,使用起来较原始,不支持C++特性。 3. **尽量用`new`和`delete`而不用`malloc`和`free`**:`new`和`delete`处理对象的构造和析构,确保对象生命周期的正确管理,而`malloc`和`free`仅分配和释放内存,不涉及对象生命周期。 4. **对应的新和删除操作符要采用相同的形式**:即如果你重载了`new`操作符,你也应该重载`delete`,以保持一致性,确保内存被正确释放。 5. **析构函数里对指针成员调用`delete`**:析构函数用于清理对象资源,如果类中有动态分配的内存,析构函数应负责释放这些内存。 6. **预先准备好内存不够的情况**:在使用`new`分配内存时,应处理`std::bad_alloc`异常,防止因内存不足导致程序崩溃。 7. **写`operator new`和`operator delete`时要遵循常规**:自定义内存分配器时,确保遵循标准分配器的行为,例如考虑对齐需求、异常安全等。 8. **避免隐藏标准形式的`new`**:如果编写了重载的`new`,可能会无意中隐藏了标准版本,导致预期之外的行为。使用`using namespace std;`时尤其需要注意这一点。 9. **如果写了`operator new`就要同时写`operator delete`**:为了保持内存分配和释放的一致性,重载`new`时应同时重载`delete`,以确保配对使用。 10. **构造函数、析构函数和赋值操作符的使用**: - 拷贝构造函数用于创建类的副本,确保深拷贝的正确性。 - 赋值操作符(`operator=`)应遵循“自赋值安全”和“右结合性”,避免意外修改对象。 - 构造函数中的初始化优于赋值,因此建议在构造函数中使用初始化列表,而不是在函数体内赋值。 11. **为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符**:这样可以确保在复制或赋值对象时,内存也被正确地复制和释放。 12. **尽量使用初始化而不要在构造函数里赋值**:初始化列表比构造函数体内的赋值更高效,且不会引发不必要的构造函数调用。 13. **初始化列表中成员列出的顺序和它们在类中声明的顺序相同**:这是C++的语法规则,程序员应遵循此规则以避免混淆。 14. **确定基类有虚析构函数**:若基类可能被多态派生,应声明虚析构函数,以确保正确销毁派生类对象。 15. **让`operator=`返回`*this`的引用**:返回`*this`使得连续赋值(如 `a = b = c;`)成为可能。 16. **在`operator=`中对所有数据成员赋值**:确保赋值操作符对所有成员执行赋值,包括隐含的成员(如虚表指针)。 17. **在`operator=`中检查给自己赋值的情况**:自我赋值可能导致未定义行为,因此应检查并处理这种情况。 18. **争取使类的接口完整并且最小**:设计简洁明了的接口有助于提高代码可读性和可维护性。 19. **分清成员函数,非成员函数和友元函数**:成员函数操作对象内部状态,非成员函数保持对象的封装,友元提供特殊访问权限,三者应根据需要合理使用。 20. **避免`public`接口出现数据成员**:直接暴露数据成员可能导致封装性破坏,应通过成员函数提供访问。 21. **尽可能使用`const`**:`const`能帮助编译器进行更多的类型检查,避免意外修改对象。 22. **尽量用“传引用”而不用“传值”**:传递引用避免了复制对象的开销,尤其是在处理大对象时。 23. **必须返回一个对象时不要试图返回一个引用**:返回引用可能创建悬挂引用,应谨慎使用。 24. **在函数重载和设定参数缺省值间慎重选择**:缺省参数可能导致编译器无法分辨重载函数,而重载则清晰地定义了不同功能的函数。 25. **避免对指针和数字类型重载**:重载操作符可能导致二义性,特别是对指针和整数类型的重载。 26. **当心潜在的二义性**:函数签名的微小差异可能导致二义性,应确保每个函数都有唯一明确定义的用途。 以上是《Effective C++》中部分条款的解读,这些知识对于提升C++编程效率和代码质量至关重要。