c++除了能使用c语言的强制类型转换外,还新增了四种强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast,主要运用于继承关系类间的强制转化,语法为:
static_cast (expression)
dynamic_cast (expression)
const_cast (expression)
reinterpret_cast (expression)
备注:new_type为目标数据类型,expression为原始数据类型变量或者表达式。
注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。
char a = 'a';
int b = static_cast(a);//正确,将char型数据转换成int型数据
double *c = new double;
void *d = static_cast(c);//正确,将double指针转换成void指针
int e = 10;
const int f = static_cast(e);//正确,将int型数据转换成const int型数据
const int g = 20;
int *h = static_cast(&g);//编译错误,static_cast不能转换掉g的const属性
if(Derived *dp = static_cast(bp)){//下行转换是不安全的
//使用dp指向的Derived对象
}
else{
//使用bp指向的Base对象
}
if(Base*bp = static_cast(dp)){//上行转换是安全的
//使用bp指向的Derived对象
}
else{
//使用dp指向的Base对象
}
dynamic_cast(e)
dynamic_cast(e)
dynamic_cast(e)
(1)指针类型
举例,Base为包含至少一个虚函数的基类,Derived是Base的共有派生类,如果有一个指向Base的指针bp,我们可以在运行时将它转换成指向Derived的指针,代码如下:
if(Derived *dp = dynamic_cast(bp)){
//使用dp指向的Derived对象
}
else{
//使用bp指向的Base对象
}
(2)引用类型
因为不存在所谓空引用,所以引用类型的dynamic_cast转换与指针类型不同,在引用转换失败时,会抛出std::bad_cast异常,该异常定义在头文件typeinfo中。
void f(const Base &b){
try{
const Derived &d = dynamic_cast(b);
//使用b引用的Derived对象
}
catch(std::bad_cast){
//处理类型转换失败的情况
}
}
const_cast,用于修改类型的const或volatile属性
const int g = 20;
int *h = const_cast(&g);//去掉const常量const属性
const int g = 20;
int &h = const_cast(g);//去掉const引用const属性
const char *g = "hello";
char *h = const_cast(g);//去掉const指针const属性
new_type必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值)。
reinterpret_cast意图执行低级转型,实际动作(及结果)可能取决于编辑器,这也就表示它不可移植。
#include
using namespace std;
int output(int p) {
cout << p << endl;
return 0;
}
typedef int (*test_func)(int);//定义函数指针test_func
int main() {
int p = 10;
test_func fun1 = &output;
fun1(p);//正确
test_func fun2 = reinterpret_cast(&output);
fun2(p);//...处有未经处理的异常: 0xC0000005: Access violation
return 0;
另外,static_cast和reinterpret_cast的区别主要在于多重继承,比如
class A {
public:
int m_a;
};
class B {
public:
int m_b;
};
class C : public A, public B {};
main(){
C c;
printf("%p, %p, %p", &c, reinterpret_cast(&c), static_cast (&c));
}
前两个的输出值是相同的,最后一个则会在原基础上偏移4个字节,这是因为static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址(c里面有m_a,m_b,转换为B*指针后指到m_b处),而reinterpret_cast却不会做这一层转换。
因此, 你需要谨慎使用 reinterpret_cast。
转载:
https://www.cnblogs.com/chenyangchun/p/6795923.html