RTTI(Run-Time Type Identification),通过运行时类型信息程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。
const_cast<>()
//去掉变量的底层const属性;
int num = 10; //num本身就是变量
const int & r = num; //const引用
const_cast<int &>(r) = 11; //去掉引用的const性质,没问题
cout<<num<<endl; //输出11
const int num = 10; //num本身就是常量
const int * p = # // 底层const指针
int *pp = const_cast<int *>(p); // 去掉指针的const性质
*pp = 11; // 可以修改成功,但行为是未定义的
cout<<num<<endl; //c++常量始终是常量,放在.rodata中,权限为r_x
//向函数指针和指向成员函数指针不可用于 const_cast
dynamic_cast<>()与static_cast<>()
//用于执行安全的向下转型,将指向子类的父类指针(引用)转换为子类指针(引用)
A * pa = new B();
B * pb = dynamic_cast<B *>(pa);//A类与B类有继承关系,
B * pb = static_cast<B *>(pa);//两者是等价的
A * pa = new A();
B * pb = dynamic_cast<B *>(pa);//返回空指针;引用抛bad_cast异常
B * pb = static_cast<B *>(pa);//不报错
//使用dynamic_cast<>()时,父类中要有虚函数,且只能用于指针和引用的转换。
//static_cast<>()是不安全的,只要用于数值的转换。
reinterpret_cast<>()
简单理解为二进制拷贝。
//声明结构体
struct A{
char c;
int n;
};
struct A a={'k',100}; //定义结构体
cout<<a.c<<endl; //输出k
cout<<a.n<<endl; //输出100
//对象是一段存储区域,使用reinterpret_cast把这段存储区域转换成一个无符号的char数组
reinterpret_cast<unsigned char *>(&a)[0] = 'a';
reinterpret_cast<unsigned char *>(&a)[1] = 'b'; //字符‘b’正好放在了内存对齐的空隙中
//下面的4条语句相当于把a.n的四字节内存修改为了:0000 0000 0000 0000 0000 0001 0000 0000
reinterpret_cast<unsigned char *>(&a)[4] = 0;
reinterpret_cast<unsigned char *>(&a)[5] = 1;
reinterpret_cast<unsigned char *>(&a)[6] = 0;
reinterpret_cast<unsigned char *>(&a)[7] = 0;
cout<<a.c<<endl; //输出字符'a'
cout<<a.n<<endl; //输出十进制的256