由于C语言中的类型转换过于松散,导致有些类型转换并无意义;因此在C++中提出了更严格的四种类型转换方式:dynamic_cast、const_cast、static_cast、reinterpret_cast。可以根据目的选择合适的运算符,从而进行类型转换。让编译器检查程序的行为是否与设计者的想法相符合。
导航
dynamic_cast:
定义:
使用一个指向基类的指针生成一个指向派生类的指针,用于RTTI中的指针或引用的类型转换安全检查,关于RTTI的介绍可参考我之前的博文RTTI(Runtime Type Identification)详解
语法:
// 语法原型
dynamic_cast< type_name > (expression)
// 示例
dynamic_cast< Base* > ps;
使用案例:
class Base{};
class Son : public Base{};
Base * pb = new Base;
Son * ps = new Son;
// dynamic_cast 允许类层次结构中 由下到上的转换 由派生类到基类的转换
Base * pb = dynamic_cast<Base *> ps;// 将派生类的指针转换为基类的指针 此时返回true
Son * ps = dynamic_cast<Son *> pb; // 将基类的指针转换为派生类的指针 此时返回false
// 向下转换false的原因:派生类有基类没有的数据及成员
const_cast:
定义:
const_cast运算符用于 执行只有一种用途的类型转换,改变值为const || volatile。即在类型转换的同时改变const常量特征。
应用场景:存在一个值,大多数情况下是const,但有时又是可以修改的。此时,可先将这个值声明为const,并在需要修改它时使用const_cast,通过类型转换实现。实现对const对象的修改。但也同时在改变常量特征的同时,可能会改变类型。
int * p = const int * q; // 报错,const不能赋值给 非const
int * p = const_cast<int *>(q); // 类型转换后正确。
语法:
// 语法原型
const_cast< type_name > (expression)
// 示例
const_cast< Base* > (ps);
使用案例:
// constcast.cpp -- using const_cast<>
#include <iostream>
using std::cout;
using std::endl;
void change(const int * pt, int n);
int main()
{
int pop1 = 38383;
const int pop2 = 2000;
cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl; // 38383 , 2000
change(&pop1, -103); // 38383 += -103
change(&pop2, -103); // 这里pop2声明为const,编译器禁止修改他 故pop2 == 2000
cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl; // 38280 , 2000
return 0;
}
void change(const int * pt, int n)
{
int * pc;
pc = const_cast<int *>(pt); // 将 const int * 转换为 int *
*pc += n; // 允许修改pop1,不允许修改pop2;编译器可接收,但不修改
// 若不用const_cast,此时const int * 的值 是不能传给非const int *指针的。
// 直接使用 pc = pt;时会报错
}
static_cast:
定义:
当且仅当type_name可被隐式转换为expression 所属的类型 或type_name所属的类型时,此时的类型转换才合法。 只可在类层次结构中的类中进行类型转换(允许向下转换 Base->Son),无关类不行。
语法:
// 语法原型
static_cast< type-name > (expression)
// 示例
static_cast< Base* > (ps);
使用案例:
Base base;
Son son;
Base * pb = static_cast<Base *> (&son); // Son->Base 允许
Son * ps = static_cast<Son *> (&base); // Base->Son 允许 但在dynamic_cast中不允许
Other * pO = static_cast<Other *> (&son); // Son->Other 不允许 无关类不能类型转换
reinterpret_cast:
定义:
用于危险的类型转换,不允许删除const,利用reinterprete_cast运算符可简化对依赖实现的操作的跟踪工作。
语法:
// 语法原型
reinterpret_cast< type-name > (expression)
// 示例
reinterpret_cast< Base* > (ps);
使用案例:
struct dat{
short a;
short b;
};
long value = 0xA224B118;
dat * pd = reinterpret_cast< dat *> (&value);
cout << hex << pd->a; // display first 2 bytes of value;
欢迎大家在评论区进行讨论,以上皆是结合学习书籍所得的个人理解与总结,若有错误恳请各位网友批评指正!