C++提供了四种类型转换方法,分别为
按照适用范围从窄到宽的顺序介绍,先从使用频率比较低的reinterpret_cast开始,然后依次是const_cast,dynamic_cast,最后介绍static_cast。
interpret是“解释,诠释”的意思,加上前缀“re”,就是“重新诠释”的意思;
cast在这里可以翻译成“转型”,这样整个词顺下来就是“重新诠释的转型”。
#include
using namespace std;
int main(int argc, char** argv) {
int num = 0x00636261;//用16进制表示32位int,0x61是字符'a'的ASCII码
int * pnum = & num;
char * pstr = reinterpret_cast(pnum);
cout<<"pnum指针的值: "<(pstr)<
reinterpret_cast 运算符并不会改变括号中运算对象的值,而是对该对象从位模式上进行重新解释
滥用 reinterpret_cast 操作很容易就会不安全。 除非所需转换本身是低级别的,否则应使用其他强制转换运算符之一。
const_cast是一种C++运算符,主要是用来去除复合类型中const和volatile属性.
//对于const变量,若想修改其值,下面的方法虽然能够通过编译,但是想修改值明显是做不到的。
const int constant = 10;
int modifier = constant;
//而下面的方法,虽然可以修改值,但是显然编译器是不会通过编译的。
const int constant = 21;
int* modifier = &constant// Error: invalid conversion from 'const int*' to 'int*'
//因此const_cast派上用场了
const int constant = 21;
const int* const_p = &constant;
nt* modifier = const_cast(const_p);
*modifier = 7;
C++强制类型转换操作符dynamic_cast
dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用。
首先,dynamic_cast依赖于RTTI信息(它对编译器有要求,需要编译器启动“运行时类型信息”这一选项),其次,在转换时,dynamic_cast会检查转换的source对象是否真的可以转换成target类型,这种检查不是语法上的,而是真实情况的检查。
dynamic_cast用于类继承层次间的指针或引用转换。主要还是用于执行“安全的向下转型(safe downcasting)”,
也即是基类对象的指针或引用转换为同一继承层次的其他指针或引用。
至于“先上转型”(即派生类指针或引用类型转换为其基类类型),本身就是安全的,尽管可以使用dynamic_cast进行转换,但这是没必要的, 普通的转换已经可以达到目的,毕竟使用dynamic_cast是需要开销的。
对于“向下转型”有两种情况。
#include
#include
class Base {
public:
virtual void show() {
std::cout << "here is Base class" << std::endl;
}
};
class Derive : public Base {
public:
virtual void show() {
std::cout << "here is Derived class" << std::endl;
}
void show1() {
std::cout << "unique show1 function" << std::endl;
}
};
int main(int argc, char ** argv) {
Base *b1 = new Base();
Base *b2 = new Derive();
Derive *d1 = dynamic_cast(b2); //第一种情况,成功
Derive *d2 = dynamic_cast(b1); //第二种情况,失败
b1->show();
b2->show();
d1->show1();
}
虚表是C++多态实现的一个重要手段,也是dynamic_cast操作符转换能够进行的前提条件。当类没有虚函数表的时候(也即一个虚函数都没有定义),不能通过编译。
C++强制类型转换操作符 static_cast
static_cast conversion
当编译器隐式执行类型转换时,大多数的编译器都会给出一个警告。
使用static_cast可以明确告诉编译器,这种损失精度的转换是在知情的情况下进行的,也可以让阅读程序的其他程序员明确你转换的目的而不是由于疏忽。
把精度大的类型转换为精度小的类型,static_cast使用位截断进行处理。
double a = 1.999;
void * vptr = & a;
double * dptr = static_cast(vptr);
cout<<*dptr<
然而它不做运行时的检查,不如dynamic_cast安全。static_cast仅仅是依靠类型转换语句中提供的信息来进行转换,而dynamic_cast则会遍历整个类继承体系进行类型检查,因此dynamic_cast在执行效率上比static_cast要差一些。
static_cast可以把任何类型的表达式转换成void类型。
另外,与const_cast相比,static_cast不能把换掉变量的const属性,也包括volitale或者__unaligned属性。
一般不能用于指针类型之间的转换比如int * 转double * ,float * 转 double* 等等。