【More Effective C++】条款2:使用C++转型操作符

C旧式转型的缺点包括:

  • 没有类型安全检查:允许将任何指针转换为其他类型指针,可能导致未定义行为的错误;
  • 难以识别和维护:语法(type)expressiontype(expression)在代码中难以被快速识别;

为了解决上述问题,推荐使用C++的四种转型操作符:

static_cast(expression)

用途:用于非多态类型的转换。

场景

  • 基本数据类型之间的转换(如intfloatfloatint)。
  • 将基类指针或引用转换为派生类指针或引用,反之亦然,类型向上转换(派生类到基类);
int firstNumber = 1, secondNumber = 3;
double result = (double)firstNumber/secondNumber; // C
double result2 = static_cast(firstNumber)/secondNumber; // C++

const_cast(expression)

用途:只用于修改类型的constvolatile属性

class Widget {};
class SpecialWidget : public Widget {};
void update(SpecialWidget* psw) {}    

SpecialWidget sw;
const SpecialWidget& csw = sw;
// update(&csw); // error: invalid conversion from ‘const SpecialWidget*’ to ‘SpecialWidget*’
update((SpecialWidget*)(&csw));
update(const_cast(&csw));
Widget *pw = new SpecialWidget;
// update(pw); // error: invalid conversion from ‘Widget*’ to ‘SpecialWidget*’
update(const_cast(pw)); // error: invalid const_cast from type ‘Widget*’ to type ‘SpecialWidget*’

 dynamic_cast(expression)

用途:只用于处理多态类型的基类和派生类之间安全向下转换,在运行时检查对象的类型安全性;

注意

  • 当转型对象是指针,转型失败,返回一个nullptr
  • 当转型对象是引用,转型失败,抛出异常
Widget *pw = new SpecialWidget;
updateViaRef(static_cast(*pw));
//  error: cannot dynamic_cast ‘* pw’ (of type ‘class Widget’) to type ‘class SpecialWidget&’ (source type is not polymorphic)
updateViaRef(dynamic_cast(*pw)); 

reinterpret_cast(expression)

用途:用于转换”函数指针“类型,不具备移植性

typedef void (*FuncPtr)();
FuncPtr funcPtrArray[10];
int doSomething() { return 0; }

// funcPtrArray[0] = &doSomething; // error: invalid conversion from ‘int (*)()’ to ‘FuncPtr’ {aka ‘void (*)()’} 
funcPtrArray[0] = reinterpret_cast(&doSomething);

利用宏定义模拟新式转换

注意:模拟的dynamic_cast不会进行是否转型成功的检查

#define static_cast(TYPE,EXPR) ((TYPE)(EXPR))
#define const_cast(TYPE,EXPR) ((TYPE)(EXPR))
#define reinterpret_cast(TYPE,EXPR) ((TYPE)(EXPR))
#define dynamic_cast(TYPE,EXPR) ((TYPE)(EXPR))

你可能感兴趣的:(More,Effective,C++,c++,开发语言)