C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast
形式:class_name
,其中class_name为以上4种,type是转换的目标类型,expression是要转换的值。
1、static_cast
任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_const。在编译期强制转换。
顶层const:表示指针本身是个常量。如:int *const p;
底层const:表示指针所指的对象是一个常量。如:int const *p;
该运算符没有运行时类型检查来保证转换的安全性。
①用于类层次结构中基类和子类之间指针或引用的转换。
进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
涉及到类,static_cast只能在有相互联系的类型中进行相互转换。
class A
{};
class B:public A
{};
class C
{};
int main()
{
A* a=new A;
B* b;
C* c;
b=static_cast(a); // 编译不会报错, B类继承A类
c=static_cast(a); // 编译报错, C类与A类没有任何关系
return 1;
}
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。
2、const_cast
const_cast只能改变运算对象的底层const,用来移除变量的const或volatile限定符。
const char m = 't';
const char *cm = &m;
char *n = const_cast<char*>(cm);
*n = 'a';
cout << *n << endl; //输出a
但是,const_cast是不能用来执行任何类型的转换的,这样都会引起编译错误的!
const char m = 't';
const char *cm = &m;
int *n = const_cast<int*>(cm); //编译出错,const_cast只能调节类型限定符,不能更改基础类型
*n = 'a';
cout << *n << endl;
3、dynamic_cast
Type必须是类的指针、类的引用或者void *,用于将基类的指针或引用安全地转换成派生类的指针或引用。
注意:
(1)dynamic_cast在运行期强制转换,运行时要进行类型检查,较安全。
(2)不能用于内置的基本数据类型的强制转换。
涉及到类,使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。
对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;
对引用进行dynamic_cast,失败抛出一个异常bad_cast,成功返回正常cast后的对象引用。
对于“向上转换”(即派生类指针或引用转换为其基类类型)都是安全地。
对于“向下转型”有两种情况:
第一,基类指针所指对象是派生类类型,这种转换是安全的;
第二,基类指针所指对象为基类类型,dynamic_cast在运行时做检查,转换失败,返回结果为0。
#include
using namespace std;
class Base{
public:
Base(){};
virtual void Show(){cout<<"This is Base calss";}
};
class Derived:public Base{
public:
Derived(){};
void Show(){cout<<"This is Derived class";}
};
int main(){
//这是第一种情况
Base* base = new Derived;
if(Derived *der= dynamic_cast(base)) {
cout<<"第一种情况转换成功"<Show();
cout<//这是第二种情况
Base * base1 = new Base;
if(Derived *der1 = dynamic_cast(base1)) {
cout<<"第二种情况转换成功"<Show();
}
else {
cout<<"第二种情况转换失败"<delete(base);
delete(base1);
return 0;
}
输出:
第一种情况转换成功
This is Derived class
第二种情况转换失败
4、reinterpret_cast
在指针之间转换,将一个类型的指针转换为另一个类型的指针,无关类型;
将指针值转换为一个整型数,但不能用于非指针类型的转换。
#include
using namespace std;
int main() {
int a=10;
int *i=&a;
long pc=reinterpret_cast<long>(i);//把一个指针转换为一个整数,即取出地址值
char *str=reinterpret_cast<char *>(i);//把int*转换为char *(比int型小),无输出
long *l=reinterpret_cast<long *>(i);//把int *转换为long *(比int型大),取出地址值(即i值)输出
cout<<*i<cout<cout<cout<<"char:"<cout<return 0;
}
输出:
10
28fedc
0x28fedc
char:
0x28fedc
总结:
去const属性用const_cast
基本类型转换用static_cast
多态类之间的类型转换用daynamic_cast
不同类型的指针类型转换用reinterpreter_cast