动态类型转换dynamic_cast
C++Primer第十九章的动态类型转换部分讲的不是很清楚,于是自己查cpp的官方手册总结一下。
dynamic_cast < new-type > ( expression )
动态类型转换是可以安全的在继承体系将指针和引用进行向上、向下和横向的转换。其表达式的类型为运行时的动态类型。具体功能如下:
一、和隐式转换,静态转换static_cast一样的功能
1、增加const属性:在expression和new-type类型相同或new-type为void*时,转换结果为expression的指针或引用。并且可以在dynamic_cast前加上const限定符实现增加const属性。
const dynamic_cast < new-type > ( expression )
2、向上转换upcast:和static_cast和隐式转换一样,dynamic_cast可以将派生类转换为基类。
二、dynamic_cast独有的功能
如果expression是一个指向具有多态特性的基类Base的指针或引用(静态类型),new-type是一个指向派生类Derived对象的指针或引用,具体进行那种转换根据expression的动态类型判断
1、向下转换downcast:expression的动态类型为指向派生类Derived的指针或引用,并且Derived仅包含一份继承自Base的对象,则转换结果为指向Derived对象的指针或引用。(相当于从expressionh的父类转换为子类)
2、横向转换sidecast:expression的动态类型为指向一个类的对象的指针或引用,该类公有继承自Base和Derivied(Derived不一定继承自Base)并且继承自Derived的子成员是明确的(必须是虚继承,不能有二义性)。则转换结果为指向Derived的指针或引用。(相当于expression动态类型对象的一个父类转换为另一个父类)
三、转换失败时如果转换目标是指针类型则返回空指针,引用类型抛出一个bad_cast异常。
这里直接使用官方例子
1 #include <iostream>
2
3 struct V {
4 virtual void f() {} // must be polymorphic to use runtime-checked dynamic_cast
5 };
6 struct A : virtual V {};
7 struct B : virtual V {
8 B(V* v, A* a) {
9 // casts during construction (see the call in the constructor of D below)
10 dynamic_cast<B*>(v); // well-defined: v of type V*, V base of B, results in B*
11 dynamic_cast<B*>(a); // undefined behavior: a has type A*, A not a base of B
12 }
13 };
14 struct D : A, B {
15 D() : B(static_cast<A*>(this), this) { }
16 };
17
18 struct Base {
19 virtual ~Base() {}
20 };
21
22 struct Derived: Base {
23 virtual void name() {}
24 };
25
26 int main()
27 {
28 D d; // the most derived object
29 A& a = d; // upcast, dynamic_cast may be used, but unnecessary
30 [[maybe_unused]]
31 D& new_d = dynamic_cast<D&>(a); // downcast
32 [[maybe_unused]]
33 B& new_b = dynamic_cast<B&>(a); // sidecast
34
35
36 Base* b1 = new Base;
37 if(Derived* d = dynamic_cast<Derived*>(b1))
38 {
39 std::cout << "downcast from b1 to d successful\n";
40 d->name(); // safe to call
41 }
42
43 Base* b2 = new Derived;
44 if(Derived* d = dynamic_cast<Derived*>(b2))
45 {
46 std::cout << "downcast from b2 to d successful\n";
47 d->name(); // safe to call
48 }
49
50 delete b1;
51 delete b2;
52 }
输出结果
downcast from b2 to d successful
参考文献:dynamic_cast conversion - cppreference.com
动态类型转换dynamic_cast的更多相关文章
- C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理
运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换dynamic_cast. 1. typeid操作符的实现 1.1. ...
- 【转载】C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理
原文:C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理 运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换 ...
- C++杂记:运行时类型识别(RTTI)与动态类型转换原理
运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换dynamic_cast. 1. typeid操作符的实现 1.1. ...
- C++高效安全的运行时动态类型转换
关键字:static_cast,dynamic_cast,fast_dynamic_cast,VS 2015. OS:Window 10. C++类之间类型转换有:static_cast.dynami ...
- 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换
作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...
- C# 4 dynamic 动态对象 动态类型转换
public class User { //使用省缺参数,一般不需要再为多态做各种静态重载了 public User( string name = "anonym", string ...
- C++运行时动态类型
RTTI 运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换dynamic_cast typeid操作符的实现 静态类 ...
- static_cast 、const_cast、dynamic_cast、reinterpret_cast 关键字简单解释
static_cast .const_cast.dynamic_cast.reinterpret_cast 关键字简单解释: Static_cast 静态类型转换 ①用于类层次结构中基类(父类)和派生 ...
- C++学习(二)
九.3.内联1)编译器用函数的二进制代码替换函数调用语句,减少函数调用的时间开销.这种优化策略成为内联.2)频繁调用的简单函数适合内联,而稀少调用的复杂函数不适合内联.3)递归函数无法内联.4)通过i ...
随机推荐
- XML数据持久化学习笔记
一.XML基础语法 1.XML结构:XML是一种树结构的文本 2.XML注释:格式:<!--在其中书写注释-->,在注释中可以单行注释也可以多行注释 3.固定内容:<?xml ver ...
- idea报错Selected Java version 11 is not supported by SDK (maximum 8)
解决方案
- MarkDown-简单学习
标题 注意:首部添加1-6个"#"号来设置标题大小: 字体 1:粗体 (注意:首尾同时添加2个"*"号来设置) 2:斜体 (注意:首尾同时添加1个"* ...
- 极简实用的Asp.NetCore模块化框架决定免费开源了
背景 在开发这个框架之前,前前后后看过好几款模块化的框架,最后在一段时间内对ABP VNext痛下狠心,研究一段时间后,不得不说 ABP VNext的代码层面很规范,也都是一些最佳实践,开发出一个模块 ...
- Python代码简化
让代码更Pythonic 当然不要过分追求简洁,不然阅读的人就遭殃了, 部分逻辑复杂的情况还应按照清晰的逻辑脉络去写方便阅读, 毕竟我们是用代码实现功能然后维护,而不是单单的炫技. ######### ...
- MySQL常用配置参数说明
1.sync_binlog sync_binlog=0,当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来 ...
- Apache Hudi 0.8.0版本重磅发布
1. 重点特性 1.1 Flink集成 自从Hudi 0.7.0版本支持Flink写入后,Hudi社区又进一步完善了Flink和Hudi的集成.包括重新设计性能更好.扩展性更好.基于Flink状态索引 ...
- 03_利用pytorch解决线性回归问题
03_利用pytorch解决线性回归问题 目录 一.引言 二.利用torch解决线性回归问题 2.1 定义x和y 2.2 自定制线性回归模型类 2.3 指定gpu或者cpu 2.4 设置参数 2.5 ...
- 使用Leaflet创建地图模块
背景 最近需要为某单位开发地图展示系统,因此开始涉略和使用Leaflet这个轻量级地图库. 创建基础地图需要以下几步 引入相关js和css文件,创建基础地图 <div id="map& ...
- Spring Boot demo系列(三):Spring Web+MyBatis Plus
2021.2.24 更新 1 概述 Spring Web+MyBatis Plus的一个Demo,内容和上一篇类似,因此重点放在MyBatis Plus这里. 2 dao层 MyBatis Plus相 ...