使用C++风格的类型转换,而不是C语言的类型转换
8.1、static_cast
和C风格转换相似可做值的强制转换。
上行转换(把派生类的指针或引用转换为基类的指针或引用),该转换经常用于消除多重继承带来的类型歧义,是相对安全的。
下行转换(把基类的指针或引用转换为派生类的指针和引用),由于没有动态类型检查,是不安全的。
8.2、dynamic_cast
主要用于下行转换,dynamic_cast具有类型检查功能。
示例:
extern void Fun(DerivedClass* pd);
void Gun(BaseClass* pb)
{
//反例:C风格强制转换,转换会导致对象布局不一致,编译不报错,运行时可能会崩溃
DerivedClass* pd = (DerivedClass*)pb;
//正例:C++风格强制转换,明确知道pb实际指向DerivedClass
DerivedClass* pd = dynamic_cast(pb);
if (pd)
Fun(pd);
}
8.3、reinterpret_cast (避免使用)
用于转换不相关的类型。尝试用reinterpret_cast将一种类型强制转换另一种类型,这破坏了类型的安全性和可靠性,是一种不安全的转换。不同类型之间尽量避免转换。
8.4、const_cast(避免使用)
const_cast用于移除对象的const属性。
反例:
unsigned const int arraySize = 1024;
int &newArraySize = const_cast(arraySize);
newArraySize = 2048;
这里如果不通过引用或者指针访问arraySize,那么arraySize的值始终是1024.可是如果被作为一个指针或者引用传给其它函数进行取值的话,会发现值变成了2048。
反例:强制去掉入参的const属性,导致函数可以对入参进行修改。
void setObj(TBase const* obj)
{
//m_pObj的定义为:
TBase *m_pObj;
m_pObj = const_cast(obj);
m_pObj->value = 123;
}
7.1、内联函数(inline function)小于10行
如果内联函数包含复杂的控制结构,如循环、分支(switch)、try-catch等语句,一般编译器将该函数视为普通函数。
虚函数、递归函数不能被用来做内联函数。
7.2、使用内联函数代替函数式宏
说明:C++中也支持宏的功能,但是宏有其自身的缺陷(例如无法对参数进行类型检查),因此,能使用内联函数的地方,一定不使用宏。
正例:
template inline TYPE_T& max(TYPE_T& x, TYPE_T& y)
{
return (x > y) ? x : y;
}
反例:
#define MAX(x, y) ((x) > (y) ? (x) : (y))
10.1、使用动宾词组为执行某操作的函数命名。如果是OOP方法,可以只有动词(名词是对象本身)。
示例:参照如下方式命名函数
void print_record(unsigned int rec_ind);
int input_record(void);
unsigned char get_current_color(void);
13.2、避免循环体内含判断语句,应将循环语句置于判断语句的代码块之外。
13.1、多重循环时,应将最忙的循环放在最内层,减少CPU切入循环层的次数。
反例:
for (row = 0; row < 100; row++)
{
for (col = 0; col < 5; col++)
{
sum += a[row][col];
}
}
正例:
for (col = 0; col < 5; col++)
{
for (row = 0; row < 100; row++)
{
sum += a[row][col];
}
}
13.2、尽量用乘法或其它方法代替除法,特别是浮点运算中的除法,因为浮点运算除法要占用较多的CPU资源。
反例:
#define PI 3.1415926
radius = circle_length / (2 * PI);
正例:
#define PI_RECIPROCAL (1 / 3.1415926)
radius = circle_length * PI_RECIPROCAL / 2;