c++中四种强制类型转换(const_cast、static_cast应用最多)

c++动态类型转换有四种const_cast、static_cast、dynamic_cast、reinterpreter_cast

前面两个用的多,但是后面的针对其设计理念有许多其他的实现方法可达到同样的效果

1. static_cast
(1)用于基本数据类型之间的转换,如把int转换为char,把int转换成enum,但这种转换的安全性需要开发者自己保证(这可以理解为保证数据的精度,即程序员能不能保证自己想要的程序安全),如在把int转换为char时,如果char没有足够的比特位来存放int的值(int>127或int<-127时),那么static_cast所做的只是简单的截断,及简单地把int的低8位复制到char的8位中,并直接抛弃高位。
(2)把空指针转换成目标类型的空指针
(3)把任何类型的表达式类型转换成void类型
(4)用于类层次结构中父类和子类之间指针和引用的转换。
对于以上第(4)点,存在两种形式的转换,即上行转换(子类到父类)和下行转换(父类到子类)。对于static_cast,上行转换时安全的,而下行转换时不安全的,为什么呢?因为static_cast的转换时粗暴的,它仅根据类型转换语句中提供的信息(尖括号中的类型)来进行转换,这种转换方式对于上行转换,由于子类总是包含父类的所有数据成员和函数成员,因此从子类转换到父类的指针对象可以没有任何顾虑的访问其(指父类)的成员。而对于下行转换为什么不安全,是因为static_cast只是在编译时进行类型坚持,没有运行时的类型检查。

一般时候static_cast用的比较多,且与const_cast结合使用可以在父子类间完成常量属性与非常量属性的相关转换
类似这样的:
const_cast

class Widget{
public:
    virtual ~Widget(){};
};

class SpecialWidget:public Widget{
};
void update(SpecialWidget *psw){};
int main()
{
Widget *pw1=new SpecialWidget();//编译运行正常
Widget *pw2=new Widget();//编译运行正常
Widget *pw;  //编译正常,运行异常
update(dynamic_cast(pw));
return 0;
}
  • static_cast的一些用法及变形
class Base1{
virtual void f(){}
};
class Base2{};
class Derived:public Base1,public Base2{};
int main(int argc, char* argv[])
{
Derived d,*pd;
Base1 *b1=&d;

//用法一
if((pd=dynamic_cast(b1))!=0){
    cout<<"pd结果指针类型为:"<<typeid(pd).name()<//用法二
Base2 *b2;
if((b2=dynamic_cast(b1))!=0){
    cout<<"b2结果指针类型为:"<<typeid(b2).name()<

结果如下:

pd结果指针类型为:P7Derived
b2结果指针类型为:P5Base2

3. const_cast
const_cast目前基本只用在const的转换上,基本无其他用法,比较单一

4. reinterpret_cast
reinterpret_cast的常用地方是转换”函数指针”类型。
如下:

typedef void (*FuncPtr)(); //定义一个无参数且无返回值的函数指针
FuncPtr funcPtrArray[10];  //定义一个长度为10的数组,数组元素是函数指针类型
int doSomething(){  return 1;};//定义一个无参返回值为int的函数
int main()
{
//funcPtrArray[0]=&doSomething;  错误,函数类型不相符
funcPtrArray[0]=reinterpret_cast(&doSomething);//函数名就是一个地址,因此取地址符是可选的

但reinterpret_cast与编译器平台相关,因此不具有移植性,使用范围也有限。
另外,倘若你用过的编译器版本比较老,不支持上面这些新用法,其实还可以用宏定义来实现强制类型转换的功能。

你可能感兴趣的:(C++,c++基础学习)