1、static_cast
静态转化static_cast 全部用于明确定义达到转换,包括编译器允许我们所做的不用强制类型转换的安全转换和不太安全但清楚定义的转换。简单来说等价与c语言的隐式转换。
void main()
{
int a = 10;
double d = 12.34;
a = static_cast<int>(d); //用于替换C中隐式转换
//int *p = static_cast<int*>(&d); //double类型的指针不能隐式转换为int类型的指针
}
2、const_cast
常量转换const_cast,如果从const转换为非const,或从volatile转换为非volatile,可以直接使用const_cast,这也是唯一允许的转换方法。const_cast只能调节类型限定符,不能改变基础类型
void main()
{
const int a = 10;
int *p = const_cast<int*>(&a); //用于去掉const 和 volatile
volatile int b = 10;
int *p1 = const_cast<int*>(&b);
double d = 12.34;
//int *p2 = const_cast<int*>(&d);// 不能转换
}
3、reinterpret_cast
重解释转换,这是最不安全的转换,reinterpret_cast 把对象假象位模式,是一个完全不同类型的对象,在使用reinterpret_cast 做任何事情之前,实际上总需要reinterpret_cast 转换回原来的类型。C++中的reinterpret_cast 主要是将数据从一种类型的转换位另一种类型。所谓“通常位操作数的位模式提供较低的重新解释”,也就是说将数据以二进制存在形式重新解释。
以二进制形式重新解释
void main()
{
double d = 12.34;
int *p2 = reinterpret_cast<int*>(&d);
cout << *p2 << endl;//直接输出是 2061584302
}
这是因为double存储数据是以1 8 13的原则存储,而reinterpret_cast直接取double的8字节中的前4个字节的数据。因此,在使用reinterpret_cast时,是需要再转换完成后重新转换回来.
void main()
{
double d = 12.34;
int *p2 = reinterpret_cast<int*>(&d);
cout << *p2 << endl;//输出 2061584302
cout << *(double*)p2 << endl;//输出 12.34
}
不安全性:
class A
{
private:
int m_a = 0;
};
class B
{
private:
int m_b = 0;
};
class D : public A, public B
{
private:
int m_c = 0;
};
void main()
{
D d;
printf("%p, %p, %p\n", &d, static_cast<B*>(&d), reinterpret_cast<B*>(&d)); //重解释
}
输出
d对象内存存储机制如下:
我们发现,再将d转换为d的父类B的指针后,reinterpret_cast<B*>(&d)的结果仍与&d是相同的,而 static_cast<B*>(&d)是指向真实的B,是正确的。而当B* b =reinterpret_cast<B*>(&d), b=&d时,之后在使用b可能会导致不正确的结果。
4、dynamic_cast
针对继承体系,主要用于类型安全的向下转化(于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换))1.dynamic_cast只能用于含有虚函数的类 2. dynamic_cast会先检查是否能转换成功,能成功则转
换,不能则返回0
class Base
{
public:
virtual void fun()const
{
cout<<"This is Base::fun()"<<endl;
}
private:
int m_a = 0;
};
class D : public Base
{
public:
void fun()const
{
cout<<"This is D::fun()"<<endl;
}
void show()const
{
cout<<"This is D::show()"<<endl;
}
private:
int m_c = 0;
};
void Active(Base *pb)
{
pb->fun();
//(dynamic_cast<D*>(pb))->show(); //避免
D *pd = dynamic_cast<D*>(pb); //用于检查向下转换的合法性
if(pd != NULL)
pd->show();
else
cout<<"非法的转换...."<<endl;
}
void main()
{
D d;
Base b;
Active(&b);
}