dynamic_cast in C++【C++学习笔记】

dynamic_cast是C++中用于多态类类型间的安全转换,尤其适用于基类到派生类的转换。它依赖于运行时类型信息(RTTI)并在转换失败时返回NULL。在涉及继承层次结构的转换时,dynamic_cast提供了一种验证机制,防止不正确的类型转换导致的程序错误。当尝试将非派生类对象转换为派生类时,转换会失败,有助于避免潜在的程序崩溃。
摘要由CSDN通过智能技术生成

73.dynamic_cast in C++

🍅概述

当我们想要做特定类型的类型转换时,有C的方式,也有C++的方式

C的方式就是类似于(int)a这般转换

而C++的方式就是使用比如static_cast, const_cast的转换,dynamic_cast亦是如此

dynamic_cast是作为一种安全机制提供给我们的转换类型方式,它做了额外的工作来确保我们实际的类型转换是有效的类型转换

dynamic_cast更像一个函数,认识到这点很重要。它不想编译时进行的类型转换,而是是在运行时计算,所以会有一定运行成本

🍅何时用

dynamic_cast是专门用于沿继承层次结构进行的强制类型转换,即dynamic_cast只用于多态类类型。意思dynamic_cast大多是用于子类父类之间的类型转换(比如从基类型转换为派生类型,或者将子类转换为基类)

比如有实体类,它的子类是敌人类和玩家类。如果把一个实体对象(这个实体对象既可以是实体类,也可以是敌人类和玩家类)转换为一个玩家对象,这会造成不确定因素。如果是玩家转换为玩家实体,那还算好。如果是敌人转换为玩家实体,敌人实体就会访问玩家独有的数据或者修改玩家独有的函数,则就会造成程序崩溃。因此,dynamic_cast常被用来做验证(如果将敌人实体转换为玩家实体,则会转换失败,dynamic_cast会返回一个NULL指针,也就是0

#include <iostream>
#include <string>

class Entity {
public:
    virtual void PrintName() {}	//这里添加虚函数是为了标志着它是多态类型,只有多态类型才能使用dynamic_cast
};

class Player : public Entity {
    
};

class Enemy : public Entity {
    
};

int main() {
    Player *player = new Player();
    Entity *actuallyPlayer = player;		//隐式转换,因为player是Entity的子类,所以player上的和Entity相同的部分可以转换到Entity上(当然要丢掉player拓展的部分)
    //上述是将子类转换为基类
    
    //下面是基类转换成子类,就会涉及到转换的问题
    Entity *actuallyEnemy = new Enemy();	//指向实体的指针指向了一个敌人类!!!
    Player *player1 = dynamic_cast<Player*>(actuallyEnemy);  //这样就会失败,将敌人转换为玩家
    Player *player2 = dynamic_cast<Player*>(actuallyPlayer);	//这样会成功
}

那么dynamic_cast是如何知道实体实际上是玩家而不是敌人的呢?要做到这一点是因为它储存了运行时的类型信息(所谓的RTTI),所以它的工作是需要RTTI是打开状态才行(VS可以把RTTI给关了)

而因为dynamic_cast是可以鉴别是否转换成功的所以可以有如下操作

#include <iostream>
#include <string>

class Entity {
public:
    virtual void PrintName() {}	//这里添加虚函数是为了标志着它是多态类型,只有多态类型才能使用dynamic_cast
};

class Player : public Entity {
    
};

class Enemy : public Entity {
    
};

int main() {
    Entity *actuallyEnemy = new Enemy();
    if (dynamic_cast<Player*>(actuallyEnemy)) {
        //如果转换成功,则往下执行下一步操作
    }
   //如果无,则无视上面的语句接着往下走
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值