写在前面
参考:链接
- static_cast
- const_cast
- reinterpret_cast
- dynamic_cast
static_cast
用于内置类型的转换,以及有继承关系的类之间的转换。
说明:基类和派生类之间进行转换时
- 向上转换:派生类向基类进行转换
- 向下转换:基类向派生类进行转换
#include<bits/stdc++.h>
using namespace std;
class A
{};
class B:public A
{};
class C
{};
int main()
{
A* a = new A;
B* b = new B;
C* c;
a=static_cast<A*>(b); // 编译不会报错, B类继承A类,向上转换
b=static_cast<B*>(a); // 编译不会报错, B类继承A类,向下转换
c=static_cast<C*>(a); // 编译报错(类型转换无效), C类与A类没有任何关系
return 0;
}
const_cast
用于同类型之间,将表达式转换成常量
reinterpret_cast
将内置类型的数据转换成其他类型的数据,也可以将指针转化为其他任何类型,或者将内置类型的数据转换成指针,类似于C中的强制类型转换 ,不到万不得已不会使用。
dynamic_cast
- 上述三种类型的转换发生在程序编译时,该转换发生在程序运行时。
- 主要用于基类和派生类之间的类型转换。同时要求基类中必须有虚函数,否则编译无法通过。
当向上转换时:用法同static_cast;
当向下转换时:dynamic_cast比static_cast更安全,要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。(如果基类指针指向的是派生类的对象,将该指针转化成派生类的指针,能够转化成功;如果基类指针指向的是基类的对象,将该指针转化成派生类的指针,返回值为空。)
#include<iostream>
#include<cstring>
using namespace std;
class A
{
public:
virtual void f()
{
cout<<"hello"<<endl;
};
};
class B:public A
{
public:
void f()
{
cout<<"hello2"<<endl;
};
};
class C
{
void pp()
{
return;
}
};
int fun()
{
return 1;
}
int main()
{
A* a1=new B;//a1是A类型的指针指向一个B类型的对象
A* a2=new A;//a2是A类型的指针指向一个A类型的对象
B* b;
C* c;
b=dynamic_cast<B*>(a1);//结果为not null,向下转换成功,a1之前指向的就是B类型的对象,所以可以转换成B类型的指针。
if(b==NULL)
{
cout<<"null"<<endl;
}
else
{
cout<<"not null"<<endl;
}
b=dynamic_cast<B*>(a2);//结果为null,向下转换失败
if(b==NULL)
{
cout<<"null"<<endl;
}
else
{
cout<<"not null"<<endl;
}
c=dynamic_cast<C*>(a1);//结果为null,向下转换失败
if(c==NULL)
{
cout<<"null"<<endl;
}
else
{
cout<<"not null"<<endl;
}
delete(a1);
return 0;
}
运行结果:
not null
null
null