- 不要动态地处理数组
这里主要有两个意思:
- 不用支持动态地基类的指针进行++、+n这种操作,因为它实际会按基类大小进行偏移计算,而非预期地按照子类的大小进行偏移计算;
2.尽量在接口中使用引用而非指针,原因就在于期望清楚地表面所讨论的是一个对象,而不是对象数组;
- 不要使用失效对象
经常容易忽略的失效对象包括:
- 语义失效对象:指向已删除对象的虚悬(dangling)指针
- 失效的迭代器:比如,在迭代器所指向的容器开始插入之后的vector<T>::iterator i
- 不要使用不安全的C语言的遗留函数:
strcpy\sprintf 的缓冲区都没有检查范围;strncpy\snprintf 虽然检查缓冲区界限,但是到达缓冲区界限时却不添加null。因此都是不安全的 - 不要使用可变长参数(…)
C++ 中可变长参数的缺点包括:- 缺乏类型安全性。 省略号本质是告诉编译器:关闭所有的检查,从此由我接管,启动reinterpret_cast
- 调用者和被调用者存在紧密耦合;
- 类类型对象的行为没有定义;
- 参数的数量未知
- 不要使用联合重新解释表示方式
比如一个联合中有一个long 类型的成员和一个指针类型的成员,给指针赋值,然后通过long读取其地址,这样会有问题:- 不同架构和编译器中sizeof(long)可能不等于sizeof (char *)
- 减少了代码的可读性;
- 不要用memcpy 复制对象、不用用memcmp 比较对象
编译器会在多态对象中嵌入一些隐藏数据(所谓的虚拟函数表指针vptr),使用虚拟继承的时候,大部分编译器实现会添加更多内部指针。一般使用中,由编译器负责管理所有这些隐藏数据。