C++强制类型转换操作符 dynamic_cast
dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用。
>>>>>>>>>>>编译器的RTTI设置>>>>>>>>>>>
dynamic_cast提供RTTI(Run-Time Type Information),也就是运行时类型识别。它对编译器有要求,需要编译器启动“运行时类型信息”这一选项。当编译器不开启RTTI时,运行含有dynamic_cast操作符的程序时会出现一个警告:
warning C4541: “dynamic_cast”用在了带 /GR- 的多态类型“ANIMAL”上;可能导致不可预知的行为
VS2010在默认下是开启RTTI的,也可以自己手动去开启或者关闭,操作如下:
视图->解决方案资源管理器
在打开的解决方案管理器中,对着项目名称右击,选择属性
配置属性-〉C/C++
>>>>>>>>>>>>>步入正题>>>>>>>>>>>>>
- dynamic_cast主要用于“安全地向下转型”
dynamic_cast用于类继承层次间的指针或引用转换。主要还是用于执行“安全的向下转型(safe downcasting)”,也即是基类对象的指针或引用转换为同一继承层次的其他指针或引用。至于“先上转型”(即派生类指针或引用类型转换为其基类类型),本身就是安全的,尽管可以使用dynamic_cast进行转换,但这是没必要的, 普通的转换已经可以达到目的,毕竟使用dynamic_cast是需要开销的。
class Base
{
public:
Base(){};
virtual void Show(){cout<<"This is Base calss";}
};
class Derived:public Base
{
public:
Derived(){};
void Show(){cout<<"This is Derived class";}
};
int main()
{
Base *base ;
Derived *der = new Derived;
//base = dynamic_cast<Base*>(der); //正确,但不必要。
base = der; //先上转换总是安全的
base->Show();
system("pause");
}
- dynamic_cast与继承层次的指针
对于“向下转型”有两种情况。一种是基类指针所指对象是派生类类型的,这种转换是安全的;另一种是基类指针所指对象为基类类型,在这种情况下dynamic_cast在运行时做检查,转换失败,返回结果为0;
#include "stdafx.h"
#include<iostream>
using namespace std; class Base
{
public:
Base(){};
virtual void Show(){cout<<"This is Base calss";}
};
class Derived:public Base
{
public:
Derived(){};
void Show(){cout<<"This is Derived class";}
};
int main()
{
//这是第一种情况
Base* base = new Derived;
if(Derived *der= dynamic_cast<Derived*>(base))
{
cout<<"第一种情况转换成功"<<endl;
der->Show();
cout<<endl;
}
//这是第二种情况
Base * base1 = new Base;
if(Derived *der1 = dynamic_cast<Derived*>(base1))
{
cout<<"第二种情况转换成功"<<endl;
der1->Show();
}
else
{
cout<<"第二种情况转换失败"<<endl;
} delete(base);
delete(base1);
system("pause");
}
运行结果:
- dynamic_cast和引用类型
在前面的例子中,使用了dynamic_cast将基类指针转换为派生类指针,也可以使用dynamic_cast将基类引用转换为派生类引用。
同样的,引用的向上转换总是安全的:
Derived c;
Derived & der2= c;
Base & base2= dynamic_cast<Base&>(der2);//向上转换,安全
base2.Show();
所以,在引用上,dynamic_cast依旧是常用于“安全的向下转型”。与指针一样,引用的向下转型也可以分为两种情况,与指针不同的是,并不存在空引用,所以引用的dynamic_cast检测失败时会抛出一个bad_cast异常:
int main()
{
//第一种情况,转换成功
Derived b ;
Base &base1= b;
Derived &der1 = dynamic_cast<Derived&>(base1);
cout<<"第一种情况:";
der1.Show();
cout<<endl; //第二种情况
Base a ;
Base &base = a ;
cout<<"第二种情况:";
try{
Derived & der = dynamic_cast<Derived&>(base);
}
catch(bad_cast)
{
cout<<"转化失败,抛出bad_cast异常"<<endl;
}
system("pause");
}
运行结果:
- 使用dynamic_cast转换的Base类至少带有一个虚函数
当一个类中拥有至少一个虚函数的时候,编译器会为该类构建出一个虚函数表(virtual method table),虚函数表记录了虚函数的地址。如果该类派生了其他子类,且子类定义并实现了基类的虚函数,那么虚函数表会将该函数指向新的地址。虚表是C++多态实现的一个重要手段,也是dynamic_cast操作符转换能够进行的前提条件。当类没有虚函数表的时候(也即一个虚函数都没有定义),dynamic_cast无法使用RTTI,不能通过编译(个人猜想...有待验证)。
当然,虚函数表的建立对效率是有一定影响的,构建虚函数表、由表查询函数 都需要时间和空间上的消耗。所以,除了必须声明virtual(对于一个多态基类而言),不要轻易使用virtual函数。对于虚函数的进一步了解,可以查看《Effective C++》
条款07:为多态基类声明virtual析构函数。
C++强制类型转换操作符 dynamic_cast的更多相关文章
- C++强制类型转换操作符 static_cast
static_cast是一个强制类型转换操作符.强制类型转换,也称为显式转换,C++中强制类型转换操作符有static_cast.dynamic_cast.const_cast.reinterpert ...
- c++强制类型转换:dynamic_cast、const_cast 、static_cast、reinterpret_cast
c++强制类型转换:dynamic_cast.const_cast .static_cast.reinterpret_cast 博客分类: C/C++ CC++C#编程数据结构 dynamic_ca ...
- C++强制类型转换操作符 const_cast
const_cast也是一个强制类型转换操作符.<C++ Primer>中是这样描述它的: 1.将转换掉表达式的const性质. 2.只有使用const_cast才能将const性质性质转 ...
- C++解析(25):关于动态内存分配、虚函数和继承中强制类型转换的疑问
0.目录 1.动态内存分配 1.1 new和malloc的区别 1.2 delete和free的区别 2.虚函数 2.1 构造函数与析构函数是否可以成为虚函数? 2.2 构造函数与析构函数是否可以发生 ...
- C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast
1. c强制转换与c++强制转换 c语言强制类型转换主要用于基础的数据类型间的转换,语法为: (type-id)expression//转换格式1 type-id(expression)//转换格式2 ...
- C++中static_cast和dynamic_cast强制类型转换
在C++标准中,提供了关于类型层次转换中的两个关键字static_cast和dynamic_cast. 一.static_cast关键字(编译时类型检查) 用法:static_cast < ty ...
- 四种强制类型转换的总结(const_cast、static_cast、dynamic_cast、reinterpreter_cast)
四种强制类型转换的总结(const_cast.static_cast.dynamic_cast.reinterpreter_cast) 转载 2011年10月03日 23:59:05 标签: stru ...
- C++里的强制类型转换符reinterpret_cast、static_cast 、dynamic_cast、const_cast 区别
C 风格(C-style)强制转型如下: (T) exdivssion // cast exdivssion to be of type T 函数风格(Function-style)强制转型使用这样的 ...
- c++强制类型转换(static_cast,const_cast,dynamic_cast,reinterpret_cast)
static_cast <typeid>(exdlvssion) static_cast 很像 C 语言中的旧式类型转换.它能进行基础类型之间的转换,也能将带有可被单参调用的构造函数或用户 ...
随机推荐
- Oracle取TOP N条记录(转载)
在SQL Server里面有top关键字可以很方便的取出前N条记录,但是Oracle里面却没有top的使用,类似实现取出前N条记录的简单方法如下: 方法1:利用ROW_NUMBER函数 取出前5条记录 ...
- JQuery学习
首先要明白一点,JQuery是一个JS的封装库,目的是为了关注点分离,让前端更加侧重于界面显示,而不是各个浏览器不同的差异性,下面是JQuery的一些常用的基本用法 一,JQuery语法 window ...
- 2795: [Poi2012]A Horrible Poem
2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 484 Solved: 235[Subm ...
- 2055 [ZJOI2009]假期的宿舍
P2055 [ZJOI2009]假期的宿舍 题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A ...
- 【HTML5+MVC4】xhEditor网页编辑器图片上传
准备工作: 创建一个MVC项目中,添加好xhEditor插件 相关用法:http://www.cnblogs.com/xcsn/p/4701497.html 注意事项:xhEditor分为v1.1.1 ...
- 【福吧资源网整理】老男孩-python运维6期 不加密
老男孩-python运维6期 不加密,连夜整理出来分享给大家老男孩的python教程确实不错. 教程目录: 下载地址:http://www.fu83.cn/thread-204-1-1.html
- Spring Security授权 AccessDecisionManager
Spring Security授权 AccessDecisionManager 博客分类: Security Spring 在前面那篇博客有一段配置: <http auto-config=& ...
- 数据字典生成工具之旅(7):NVelocity实现代码生成器
这个系统好久没有更新了,人也慢慢变懒了,从现在开始每个月至少写三篇文章,欢迎大家监督.对了预告一下,该系列完成以后将为大家带来WebApp开发系列篇,敬请期待.先上几张图,放在文章最后面欢迎预览! 本 ...
- leetcode - 位运算题目汇总(下)
接上文leetcode - 位运算题目汇总(上),继续来切leetcode中Bit Manipulation下的题目. Bitwise AND of Numbers Range 给出一个范围,[m, ...
- Ace - Responsive Admin Template
Ace简介: Ace 是一个轻量.功能丰富.HTML5.响应式.支持手机及平板电脑上浏览的管理后台模板,基于CSS框架Bootstrap制作,Bootstrap版本更新至 3.0,Ace – Resp ...