C++中4种强制类型转换的区别总结

2020-01-06 15:58:57王冬梅

另外,dynamic_cast还支持交叉转换,如下所示。


class A
{
public:
 int m_iNum;
 virtualvoid f(){}
};
 
class B:public A
{
 
};
 
class D:public A
{
 
};
 
void foo()
{ 
 B *pb = new B; 
 pb->m_iNum = 100; 
 D *pd1 = static_cast<D *>(pb); //compile error 
 D *pd2 = dynamic_cast<D *>(pb); //pd2 is NULL 
 deletepb; 
}

在函数foo中,使用static_cast进行转换是不被允许的,将在编译时出错,而使用dynamic_cast转换则是允许的,结果是空指针。

三、reinterpret_cast

用法:reinterpret_cast (expression)

type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。

它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。

该运算符的用法比较多。

(static_cast .与. reinterpret_cast比较,见下面 )

该运算符平台移植性比价差。

四、const_cast

用法:const_cast (expression)

该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。

常量指针被转化成非常量指针,并且仍然指向原来的对象;

常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

volatile和const类型,举例如下所示。


class B
{
public: 
 int m_iNum; 
}
 
void foo()
{
 const B b1; 
 b1.m_iNum = 100; //comile error 
 B b2 = const_cast<B>(b1); 
 b2. m_iNum = 200; //fine 
}

上面的代码编译时会报错,因为b1是一个常量对象,不能对它进行改变;

使用const_cast把它转换成一个非常量对象,就可以对它的数据成员任意改变。注意:b1和b2是两个不同的对象。

五、比较

(1)dynamic_cast vs static_cast


class B 
{ 
 ... 
};
 
class D : public B 
{ 
 ...
};
 
 
void f(B* pb)
{ 
 D* pd1 = dynamic_cast<D*>(pb); 
 D* pd2 = static_cast<D*>(pb); 
}

If pb really points to an object of type D, then pd1 and pd2 will get the same value. They will also get the same value if pb == 0.

If pb points to an object of type B and not to the complete D class, then dynamic_cast will know enough to return zero. However, static_cast relies on the programmer's assertion that pb points to an object of type D and simply returns a pointer to that supposed D object.

即dynamic_cast可用于继承体系中的向下转型,即将基类指针转换为派生类指针,比static_cast更严格更安全。dynamic_cast在执行效率上比static_cast要差一些,但static_cast在更宽上范围内可以完成映射,这种不加限制的映射伴随着不安全性。static_cast覆盖的变换类型除类层次的静态导航以外,还包括无映射变换、窄化变换(这种变换会导致对象切片,丢失信息)、用VOID*的强制变换、隐式类型变换等…