提升C++编程效率与实践技巧

需积分: 15 0 下载量 93 浏览量 更新于2024-07-29 收藏 1.52MB PDF 举报
"More_Effective_C++.pdf 是一本由Scott Meyers编著的关于C++编程进阶的书籍,由侯捷翻译并撰写译序和导读。书中详细讨论了35个C++编程的最佳实践和策略,涵盖了基础议题、运算符、异常处理、效率提升等多个方面,旨在帮助读者提升C++编程的技能和代码质量。" 本书中的知识点包括: 1. **指针与引用的区别**:指针可以为空,可以被重新赋值,而引用一旦初始化后必须始终引用一个对象,不能改变引用目标。 2. **尽量使用C++风格的类型转换**:推荐使用`static_cast`, `dynamic_cast`, `reinterpret_cast`, 和 `const_cast`代替传统的类型转换方法,因为它们提供了更好的类型检查和控制。 3. **避免对数组使用多态**:由于数组没有虚拟函数,多态性无法在数组上下文中工作,可能导致意外的行为。 4. **避免无用的缺省构造函数**:如果类不打算被默认构造,应声明为私有以避免不必要的实例化。 5. **谨慎定义类型转换函数**:过度或不适当的类型转换可能会导致代码难以理解和维护,甚至引入安全风险。 6. **自增和自减操作符的前缀和后缀形式**:前缀形式会立即更新操作数的值,而后缀形式会返回操作数的旧值。 7. **不要重载逻辑运算符"&&", "||", 或逗号运算符","**:这些运算符有特殊的短路行为,重载可能导致预期之外的行为。 8. **理解NEW和DELETE的不同含义**:`new`分配内存并构造对象,`delete`则释放内存并析构对象。了解何时应该使用配对的`new[]`和`delete[]`。 9. **使用析构函数防止资源泄漏**:析构函数是释放资源的关键,特别是在异常处理中。 10. **在构造函数中防止资源泄漏**:确保在构造过程中,即使发生异常,资源也能正确释放。 11. **禁止异常信息传递到析构函数外**:析构函数不应抛出异常,否则可能导致资源管理错误。 12. **理解抛出异常与传递参数或调用虚函数的差异**:异常处理打断了正常的执行流程,可能导致栈展开和资源清理。 13. **通过引用捕获异常**:这允许在捕获异常时保持原始异常信息的完整性。 14. **审慎使用异常规格(EXCEPTION SPECIFICATIONS)**:异常规格可能导致编译器进行过多的检查,降低代码的可移植性和效率。 15. **了解异常处理的系统开销**:异常处理虽然强大,但也有一定的性能成本。 16. **牢记80-20法则**:在优化代码时,通常20%的代码占用了80%的运行时间,应优先关注这部分代码。 17. **考虑使用懒惰计算法(LAZY EVALUATION)**:延迟计算直到真正需要时,以减少不必要的计算。 18. **分期摊还期望的计算**:当一个操作可能很昂贵时,可以考虑分阶段进行,以减少一次性开销。 19. **理解临时对象的来源**:临时对象的生命周期和复制行为对性能和代码行为有直接影响。 20. **协助完成返回值优化**:通过返回对象的引用或使用移动语义来优化返回大对象的过程。 21. **通过重载避免隐式类型转换**:限制不必要的类型转换可以提高类型安全性。 22. **考虑用运算符的赋值形式(OP=)取代其单独形式(OP)**:为了实现正确的赋值行为,如右值引用和深拷贝等。 23. **考虑变更程序库**:有时候,为了性能和代码质量,可能需要寻找更高效或者更合适的第三方库。 24. **理解虚拟函数、多继承、虚基类和RTTI的代价**:这些特性提供了强大的功能,但也带来了额外的存储和运行时开销。 本书通过深入讲解每个议题,为C++程序员提供了实用的指导,帮助他们编写更高效、更健壮的代码。

优化代码 def cluster_format(self, start_time, end_time, save_on=True, data_clean=False, data_name=None): """ local format function is to format data from beihang. :param start_time: :param end_time: :return: """ # 户用簇级数据清洗 if data_clean: unused_index_col = [i for i in self.df.columns if 'Unnamed' in i] self.df.drop(columns=unused_index_col, inplace=True) self.df.drop_duplicates(inplace=True, ignore_index=True) self.df.reset_index(drop=True, inplace=True) dupli_header_lines = np.where(self.df['sendtime'] == 'sendtime')[0] self.df.drop(index=dupli_header_lines, inplace=True) self.df = self.df.apply(pd.to_numeric, errors='ignore') self.df['sendtime'] = pd.to_datetime(self.df['sendtime']) self.df.sort_values(by='sendtime', inplace=True, ignore_index=True) self.df.to_csv(data_name, index=False) # 调用基本格式化处理 self.df = super().format(start_time, end_time) module_number_register = np.unique(self.df['bat_module_num']) # if registered m_num is 0 and not changed, there is no module data if not np.any(module_number_register): logger.logger.warning("No module data!") sys.exit() if 'bat_module_voltage_00' in self.df.columns: volt_ref = 'bat_module_voltage_00' elif 'bat_module_voltage_01' in self.df.columns: volt_ref = 'bat_module_voltage_01' elif 'bat_module_voltage_02' in self.df.columns: volt_ref = 'bat_module_voltage_02' else: logger.logger.warning("No module data!") sys.exit() self.df.dropna(axis=0, subset=[volt_ref], inplace=True) self.df.reset_index(drop=True, inplace=True) self.headers = list(self.df.columns) # time duration of a cluster self.length = len(self.df) if self.length == 0: logger.logger.warning("After cluster data clean, no effective data!") raise ValueError("No effective data after cluster data clean.") self.cluster_stats(save_on) for m in range(self.mod_num): print(self.clusterid, self.mod_num) self.module_list.append(np.unique(self.df[f'bat_module_sn_{str(m).zfill(2)}'].dropna())[0])

2023-05-25 上传