C++中的类型转换

简介

C 的强转:

C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换都是 TYPE b = (TYPE) a;
C++的类型转换

四种类型转换操作符对应不同的场合应用

强制类型转换-> 

1. const_cast        字面上的理解就是去 const 属性 

2. static_cast       命名上理解是静态类型转换 如 int 类型转化为 char

3. dynamic_cast      命名上理解是动态类型转换,如子类和父类之间的多态类型转换

4. reinterpret_cast  仅仅重新解释类型,但没有进行二进制的转换

1.  const_cast

//const_cast.cpp

#include<iostream>
#include<string>

using namespace std;

int main(int argc, char const *argv[]){
   string man= "man";
   cout<<man<<endl;
   const string woman = "woman";
   //不能修改woman字符串中的内容
   //woman = "man";
   const string* const_p = &woman;
   string* modifier = const_cast<string*>(const_p);
   *modifier = "man fix up";
   //输出 man fix up
   cout<<*modifier<<endl;
   //修改了woman字符串中的内容 输出 man fix up
   cout<<woman<<endl;
   cout<<modifier<<endl;
   return 0;
}

输出结果:

[root@localhost lesson_13]# g++ const_cast.cpp -o const_cast
[root@localhost lesson_13]# ./const_cast
man
man fix up
man fix up
0x7fff9b72ac08
const int constant = 21;
const int* const_int = &constant;
int* modifier_int = const_cast<int*>(const_int);
*modifier_int = 100;
cout<<"constant: "<<constant<<endl; //21
cout<<"const_int:"<<*const_int<<endl; //100
cout<<"modifier_int: "<<*modifier_int<<endl; //100

用传统的方式实现 const_cast 去const转换

标准转换运算符是可以用传统转换方式实现的。const_cast 实现原因就在于C++对于指针的转换是任意的,它不会检查类型,任何指针之间都可以进行互相转换,因此const_cast就可以直接使用显示转换(int*)来代替,如下:

#include<iostream>
#include<string>

using namespace std;

int main(int argc, const char* argv[]){
   const int constant = 20;
   const int* const_p = &constant;
   int* modifier = (int*)(const_p);
   *modifier = 30;
   cout<<*modifier<<endl; //30
   cout<<constant<<endl; //20
   return 0;
}

上面的部分代码也可以简化成如下代码:

const int constant = 20;
int* modifier = (int*)(&constant);

用来替换 const_cast

const int constant = 21;
int* modifier = const_cast<int*>(&constant);

使用 const_cast 的场景:

1. 在函数需要的传入参数是普通指针,而且知道对指针所指向的内容不会进行修改,而传入的实际参数只能是常量指针,那么此时就会使用去const_cast<Type>(variable) 来进行处理,例子如下:

#include<iostream>
#include<string>

using namespace std;

void print(int* val){
   cout<<"val is: "<<*val<<endl;
}

int main(int argc, const char* argv[]){
   const int constant = 20;
   //print(&constant);//error: invalid conversion from ‘const int*’ to ‘int*’
   print(const_cast<int*>(&constant));
   return 0;
}

2. static_cast

1. 基础类型之间转换,如 float 转成 int ,int 转成 unsigned int 等。
2. 指针与void之间相互转换,比如:float * 转成 void* ,Bean* 转成 void* 函数指针转成 void* 等。
3. 子类指针/引用 与 父类指针/引用转换。

//static_cast.cpp

#include <iostream>
using namespace std;

class Parent {
public:
   //virtual
   void check(){
        cout<< "parent" <<endl;
    }
};


class Child:public Parent {
public:
    void check(){
        cout <<"child"<<endl;
    }

};


void showMessage(void* msg){
   cout<<*((int*)msg)<<endl;
}



int main(int argc, char const *argv[]){
  //1. 子类指针与父类指针转换
  Parent* p = new Parent;
  Child* c  = static_cast<Child*>(p);
  c->check();
  //1. 如果 Parent的check方法加上 virtual,则输出 parent
  //2. 如果 Parent的check方法不加上 virtual,则输出 child
  if(!c){
     cout<<"转换失败"<<endl;
  }

  //基础类型之间转换
  float f_data = 3.14;
  int i_data_old = f_data;
  cout<<"i_data_old is : "<<i_data_old<<endl;

  int i_data = static_cast<int>(f_data);
  cout<<"i_data is : "<<i_data<<endl;

  //指针与void* 指针之间转换
  int age = 25;
  int* pInt = &age;
  showMessage(pInt);

  return 0;
}

输出结果:

[root@localhost lesson_13]# ./static_cast
child
i_data_old is : 3
i_data is : 3
25

3. dynamic_cast

主要将基类指针或者引用安全地转为派生类,在运行期对可疑的转型操作进行安全检查,仅对多态有效。

#include <iostream>
using namespace std;

class Parent {
public:
   virtual void check(){
        cout<<"parent.." <<endl;
    }
};


class Child:public Parent {
public:
    void check(){
        cout <<"child.."<<endl;
    }

};

int main(int argc, char const *argv[]){
  Parent *p = new Parent;
  Child *c  = dynamic_cast<Child*>(p);
  //c->check();
  // Parent check 加上 virtual 输出 p
  // cout<<"*c is "<<c<<endl; //输出 *c is 0,表示动态转换失败
  if(!c){
     cout<<"转换失败"<<endl;
  }
  Parent *pp = new Child;
  Child *cc = dynamic_cast<Child*>(pp);
  if (cc){
     cout<<"转换成功"<<endl;
  }
  cc->check();
  return 0;
}

输出结果:

[root@localhost lesson_13]# ./dynamic_cast
转换失败
转换成功
child..

从上面可以看出,在动态转换的时候,只有父类的指针指向的对象是子类的时候,才会将父类指针动态的转换成子类的指针。

4. reinterpret_cast

对指针,引用进行原始转换

#include <iostream>
using namespace std;

int check(){
  cout<<"method check"<<endl;
  return 0;
}

int main(int argc, char const *argv[]){
  // c++ reinterpret_cast
  typedef void(*FuncPtr)();
  FuncPtr funcPtr;
  funcPtr = reinterpret_cast<FuncPtr>(&check);
  funcPtr();
  return 0;
}

输出:

method check

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值