简介
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
参考: