c++:浅谈强制类型转换

来源:互联网 发布:php 数组转换字符串 编辑:程序博客网 时间:2024/06/18 13:40

c语言中我们经常使用到强制类型转换,但为什么c++中还要学习新的强制类型转换呢?当然是为了更加方便和灵活地控制不同类型间的强制转换。

针对不同的应用需要c++制定了一套专用的强制类型转换:static_cast reinterpret_cast const_cast dynamic_cast四种操作符。<

接下来,让我们一一道来!
首先,我们要分清隐式类型转换和显示的强制类型转换。
隐式类型转换

int main(){    int i = 1;    double d = i;//这里i赋值给d过程会生成具有常性临时变量     printf("%d,%.2f\n",i,d);    return 0;}

这里写图片描述
显式的类型转换

int main(){    int i=1;    int *p =& i;    int a = (int)p;//将指针类型强制转换为整型    printf("%x,%d\n",p,a);    return 0;}

这里写图片描述

static_cast
-相关类型的转换,类似C语言隐式类型转换

static_cast用于非多态类型的转换(静态转换),任何标准转换都可以它,但它不能用于两个不相关类型进行转换。

什么是相关类型呢?比如 int和char,double是相关类型,int和int*是非相关类型。
举个例子,将int型变量转换为double类型:

#include<iostream>using namespace std;int main(){    int i = 1;    double d = static_cast<double>(i);    printf("%d,%.2f\n",i,d);}

这里写图片描述
reinterpret_cast

-不相关类型的转换,类似C语言强制类型的转换
把一个指针类型转换成一个整数类型等
eg:

int *p=&i;int a=reinterpret_cast<int>(p);

其实reinterpret_cast强制转换也是一个比较bug的操作,要小心使用!

#include<iostream>using namespace std;typedef void (*FUNC)();int Something(int i){    cout<<"Something"<<endl;    return 0;}int main(){    FUNC f=reinterpret_cast<FUNC>(Something);    f();}

这里写图片描述

reinterpret_cast可以使编译器以FUNC的方式去看待Something。上面转换函数指针的代码是不可移植的,通过没有传参数的函数居然可以调用这个有参数的函数,产生了不确定结果,所以建议不到万不得已不要使用reinterpret_cast转换符。

const_cast
-不相关类型转换,相当于C语言强制类型转换去掉const属性

最常用的用途就是删除变量的const属性,方便赋值。

int main(){    const int a = 1;    int *p = const_cast<int*>(&a);    *p = 2;    cout<<a<<endl;}

强制类型转换后大多数人无疑会以为输出2,看看结果:
这里写图片描述

为什么打印出来的是1呢?打开监视窗口瞧瞧:
这里写图片描述

好了,我来解释一下。
监视窗口看到的数据是从内存里读取到的,而打印窗口里的数据是从寄存器里读取到的。我们都知道编译器具有优化功能,当你将变量a定义为const类型,编译器认为这个数据不会再改变并且优先将其放入寄存器中。从而导致了我们明明改变了a的值却不能显式地打印出来。为了解决这个问题就要用到c++里的一个关键字。

volatile :作用防止编译器优化,直接从内存读取
这里写图片描述
c语言的强制类型转换可以达到以上三种情况的功能,对于最后一种强制类型转换特属于c++。

dynamic_cast
-用于将一个父类对象的指针转换为子类对象的指针或者引用(动态转换)

首先说明一下 向上转型:子类对象指针->父类指针/引用(不需要转换)
向下转型:父类对象指针->子类对象指针
在类的转换时,在向上转型时,dynamic_cast和static_cast的效果是一样的。在向下转型时,dynamic_cast具有类型检查的功能,比static_cast更安全。它会检查是否能够转换成功,能成功则转换,不能则返回NULL,检测在运行时进行。
这个强转有一个重要的作用,就是可以在一个继承关系里区分谁是父类谁是子类?

class AA  {  public:      virtual void fun1()      {          cout << "hello" << endl;      }  public:      int a;  };  class BB :public AA  {  public:      virtual void fun1()      {          cout << "hi" << endl;      }  public:      int b;  };  int main()  {      AA* q = new AA();      BB* p = new BB();      AA* a;      BB* b;      b = dynamic_cast<BB*>(q);      if (b == NULL)      {          cout << "AA是基类" << endl;      }      else{          cout << "AA是子类" << endl;      }      a = dynamic_cast<AA*>(p);      if (a == NULL)      {          cout << "BB是基类" << endl;      }      else      {          cout << "BB是子类" << endl;      }      system("pause");      return 0;  }  

这里写图片描述

原创粉丝点击