C++ 具有两种形式的类型转换,一种是新型的命名的类型转换,一种是从C语言继承而来的老式的类型转换。
Named Casts 命名转换
cast-name(expression): static_cast, const_cast, dynamic_cast, and reinterpret_cast
static_cast:用于编译器可自动进行的类型转换,如 int to char, double to int,默认情况下编译器会给出警告(大类型到小类型,丢失数据),使用static_cast可以避免这种警告;用于从void*转换回原来的类型,或者相反。
例如:
float f = 1.23;
int a = static_cast(f);
void* p = somePtr;
int* intPtr = static_cast(p);
const_cast:与const属性有关,把const的转成non-const的,反之亦然。
例如:
void str_cpy(char* src, char* dst);
const char* pHello = "hello";
char szHello[20];
str_cpy(const_cast(pHello), szHello);
dynamic_cast: 动态转换,常用在父类指针(引用)到子类(引用)的转换,转换时首先进行类型兼容性检查,若类型不兼容,则失败(指针时返回0,引用时抛出异常bad_cast)。
例如:
CBase* basePtr;
CDerived* derPrt = dynamic_cast(basePtr); // return 0 if fails
CBase* baseRef = someObject;
CDerived& derRef = dynameic_cast(baseRef); // throw std::bad_cast if fails
reinterpret_cast: 重新解释被转换类型的底层模式。(最危险的类型转换)
例如:
int* intPtr;
char* chPtr = reinterpret_cast(intPtr);
虽然此类转换总是成功的,但是也是最危险的。
当使用上面例子中的chPtr指针去初始化一个字符串 string str(chPtr),显然,这会产生错误。
Old-Style Casts 老式转换
老式转换是C语言中的类型转换模式
形如: (Type) expression 或 Type(expression)
老式转换依照具体内容,具有和命名转换一样的效果
float f;
int a = (int)f; // static_cast
char* p = (char*)"hello"; // const_cast
int* intPtr;
char* p = (char*)intPtr; // reinterpret_cast
小结:
应该避免类型转换,类型转换往往预示着设计上的失误。
是用C++标准中的命名类型转换代替老式的C语言的强制转换。
转换到void*时,尤其注意具有继承层次的类型之间的转来转去(多继承时,转成不同的基类指针是有地址偏移的)
参考资料:
1、C++ Primer 英文第四版
2、http://www.vckbase.com/document/viewdoc/?id=1651