文章目录
1.指针与引用
在以下情况只能使用指针:
- 存在不指向任何对象的可能(即空指针)
- 可能改变指向的对象
在以下情况推荐使用引用:
- 重载某个操作符时,返回引用
- 必须指向一个对象且不再改变指向
2.类型转换
使用C++风格的类型转换,如下:
- static_cast:静态类型转换,常用于基本类型转换
- const_cast:去除变量的const属性
- dynamic_cast:动态类型转换,安全的基类和子类之间转换;运行时类型检查
- reinterpret_cast:强制类型转换,重新解释操作数的位模式,很难保证移植性
3.不要对数组使用多态
4.避免无参构造
没有默认构造可能带来的问题:
- 不能建立对象数组
- 无法在许多模板容器使用
- 虚基类很难实现,即所有的派生类需要给基类提供参数
5.谨慎定义类型转换函数
隐式转换会带来很大意料之外的结果,故需要谨慎使用单参数的构造函数和类型转换函数。
- 当不希望发生隐式转换时用explicit关键字声明构造函数
6.++(–)前缀与后缀的区别
- 前缀返回值为引用,后缀返回值为const对象
- 后缀必须创建一个临时对象作为返回值,故应该尽量使用前缀来提高效率
7.不要重载"&&"、"||“和”,"
- 这三个操作符用到了短路求值,一旦确认了表达式的值将停止运算(并非所有的参数都会计算)。而重载之后用的是函数调用,所有参数都需要计算,且参数的计算顺序不是一个标准约定。
8.各种new与delete
- new操作(operator new)与new操作符(new operator):new操作符调用new操作来为对象分配内存;函数 operator new 通常这样声明:void * operator new(size_t size);
- placement new:只构造对象,不为对象分配内存
9.避免产生不必要的对象
- 产生临时对象的场景:C++在建立一个未命名的非堆对象会产生临时对象,这种对象一般在隐式转换或者函数返回对象时产生
- 优化建议:
1.返回引用或指针(不要返回一个临时对象的引用或指针,因为临时对象的生命周期只在函数内,函数调用结束即被释放了)
2.通过重载避免隐式转换
3.考虑用op=(+=、-=…)取代单独的op(+、-…)
4.选择合适的程序库,比如iostream和stdio,iostream是类型安全、可扩展的,但是效率不如stdio,stdio产生的执行文件相比而言尺寸小且执行速度快
10.理解虚函数、多继承、虚基类和RTTI所需的代价
RTTI——运行阶段类型识别详细说明
1.虚函数:大多数编译器是用虚表或者虚表指针来实现虚函数的调用,所需要付出得代价有如下三个:虚函数会需要虚表空间,会使对象更大;在每个包含虚函数的类的对象里,得为额外得指针付出代价;虚函数不能是内联函数
2.多继承会带来多个虚表(每一个基类对应一个)
3.RTTI耗费得空间是虚表再额外加上储存type_info对象得空间
11.编程技巧
1.限制对象数量:通过私有化构造函数(无法被继承和包容)或实现对象计数实现
2.禁止堆对象:通过私有化operator new实现