C++中四种类型转换运算符

       由于C语言中的类型转换过于松散,导致有些类型转换并无意义;因此在C++中提出了更严格的四种类型转换方式:dynamic_cast、const_cast、static_cast、reinterpret_cast。可以根据目的选择合适的运算符,从而进行类型转换。让编译器检查程序的行为是否与设计者的想法相符合。

导航

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;

欢迎大家在评论区进行讨论,以上皆是结合学习书籍所得的个人理解与总结,若有错误恳请各位网友批评指正!

  • 36
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值