目录
一.const_cast
const_cast类型的转换指的是去掉常量属性的一种类型转换。
例如,在C语言中,我们可以进行以下操作
const int a = 10;
int* p1 = (int*)&a;
而如果在C++中,就可以使用以下语法
const int a = 10;
int* p2 = const_cast<int*>(&a);
这两种方法所生成的指令是一样的,但二者在编译期间的处理方式是有所不同的,例如在C语言中
const int a = 10;
char* p1 = (char*)&a;
//or
double* p1 = (double*)&a;
可以用不同类型的指针指向a,但在C++中不可以
因为const_cast做得只是去除变量的常性,不能做变量类型的转换。 这样做更安全。
同时我们还要注意,const_cast中的类型必须是指针,引用或指向对象类型成员的指针,即不能写为下面这种形式
二.static_cast
static_cast提供编译器认为安全的类型转换,例如在继承中,可以用派生类对象给基类对象赋值。
三.reinterpret_cast
reinterpret_cast类似于C语言中的强制类型转换,例如
int* p = nullptr;
double* b = reinterpret_cast<double*>(p);
缺点就是不够安全。
四.dynamic_cast
dynamic_cast主要用于继承结构中,可以支持RTTI类型识别的上下转换。
例如,有如下一段代码
#include<iostream>
using namespace std;
class Base
{
public:
virtual void func() = 0;
};
class Derive1 :public Base
{
public:
void func()
{
cout << "call Derive1::func" << endl;
}
};
class Derive2 :public Base
{
public:
void func()
{
cout << "call Derive2::func" << endl;
}
};
void show(Base* p)
{
p->func();
}
int main()
{
Derive1 d1;
Derive2 d2;
show(&d1);
show(&d2);
}
运行结果:
现在,我们在Derive2这个类中新增加了一个函数func_2,要求以后当指向Derive2对象的基类指针调用虚函数func()发生动多态时,不再调用func()函数,而调用func_2()函数。
class Derive2 :public Base
{
void func()
{
cout << "call Derive2::func" << endl;
}
void func_2()
{
cout << "call Derive2::func_2" << endl;
}
};
这时我们就可以借用dynamic_cast类型转换,具体代码如下:
#include<iostream>
using namespace std;
class Base
{
public:
virtual void func() = 0;
};
class Derive1 :public Base
{
public:
void func()
{
cout << "call Derive1::func" << endl;
}
};
class Derive2 :public Base
{
public:
void func()
{
cout << "call Derive2::func" << endl;
}
void func_2()
{
cout << "call Derive2::func_2" << endl;
}
};
void show(Base* p)
{
Derive2* _p = dynamic_cast<Derive2*>(p);
/*dynamic_cast会检查p指针指向的是否是一个Derive2类型的对象
这一过程是系统通过p的vfptr访问vftable,来查看当前vftable中存放的RTTI信息实现的
如果是,则会返回Derive2对象的地址给_p,
否则返回nullptr*/
if (_p != nullptr)
{
_p->func_2();
}
else
{
p->func();
}
}
int main()
{
Derive1 d1;
Derive2 d2;
show(&d1);
show(&d2);
}
运行结果: