一、static_cast
static_cast用于在相关类型的指针之间进行转换,还可以显式地指向标准数据类型的类型转换。用于指针时,static_cast实现了基本的编译阶段检查,确保指针被转换为相关类型。在C语言中,可将一个对象的指针转换为完全不相关的类型,而编译器也不会报错。使用static_cast可将指针向上转换为基类类型,也可向下转为派生类型。
CAnimal *pBase = new CDog;
CDog* pDog = static_cast
(pBase); //ok
CUnrelated* pUnrelated = static_cast
(pBase); //error
static_cast只验证指针类型是否相关,而不会执行任何运行阶段检查。如果是下面的情况也不会报错:
CAnimal *pBase = new CAnimal;
CDog* pDog = static_cast
(pBase); //compile ok but run error
其中pDog指向的是一个不完整的CDog对象,因为实际上他指向的是CAnimal对象类型。这会导致在运行阶段,使用该指针调用CDog的方法会导致意外的结果。
二、dynamic_cast
动态类型转换在运行阶段执行类型转换,可以检查dynamic_cast操作的结果以判断类型转换是否成功。
CAnimal *pBase = new CDog;
CDog* pDog = static_cast
(pBase); //ok
if (pDog) //check for sucess of cast
pDog->move();
给定一个基类对象,程序员可能不确定它属于哪种派生类型,这时可以使用dynamic_cast在运行阶段判断其类型,并在安全时使用转换后的指针。
void DetermineType(CAnimal *pAnimal)
{
CDog* pDog = static_cast
(pAnimal);
if(pDog)
pDog->move();
CCat* pCat = static_cast
(pAnimal);
if(pCat)
pCat->run();
}
三、reinterpret_cast
reinterpret_cast是C++中与C风格类型转换最接近的类型转换运算符。它不管类型是否相关,强制编译器接收static_cast通常不允许的类型转换。通常用于低级程序(如驱动程序).
四、const_cast
const_cast让程序员关闭对象的访问修饰符const。
CSomeClass
{
public:
void show(); // ought to be a const member
}
如果是下面这种情况,将会编译错误
void showAllData{const CSomeClass& mData}
{
mData.show(); // compile error
}
在这种情况下,调用show的语法如下:
void showAllData{const CSomeClass& mData}
{
CSomeClass& rData = const_cast
(mData);
rData.show(); // ok
}
另外,const_cast也可用于指针。
五、static_cast和reinterpret_cast区别
C++通过指针来访问成员的过程,实际上是根据指针的类型,找到改类定义,并从中找到要访问的成员的地址偏移,然后从对象指针开始加上偏移,便得到了成员的地址,然后进行访问操作。所以类定义的作用之一在于,确定成员的内存偏移。
static_cast会在编译期将指针在类的内存空间内移动,并最终指向到你转换到的内存上。在上面的例子中,当将CAnimal*的指针转型为CDog*型指针时,实际上将指针的数值修改了,指向了内存中CDog类的开头位置。当使用转换后的指针访问CDog的成员时,先到CDog类定义查到CDog的内存分布,然后进行指针偏移,访问。一切都是正确的。
reinterpret_cast并不会在转型是修改指针的值,而是告诉编译期,这个指针是某个类型的指针,仅此而已。所以当使用此转型方式转换CAnimal*的指针到CDog*类型时,指针仍然指向原来的位置,即CAnimal*的开头。这时如果访问CDog*的成员move,那么先到CDog上查到move的地址偏移,那么你实际是将指针偏移到了CAnimal类的xx成员处,访问的是xx的内容。这种错误是编译器不明白的,你的程序即将崩溃。所以,请谨慎使用reinterpret_cast。
C++ 类型转换
最新推荐文章于 2024-10-03 20:31:03 发布