在面向对象程序设计中,有时我们需要在运行时查询一个对象是否能作为某种多态类型使用。与Java的instanceof,以及C#的as、is运算符类似,C++提供了dynamic_cast函数用于动态转型。相比C风格的强制类型转换和C++ reinterpret_cast,dynamic_cast提供了类型安全检查,是一种基于能力查询(Capability Query)的转换,所以在多态类型间进行转换更提倡采用dynamic_cast。本文主要介绍dynamic_cast的意义,用法和注意事项。
基本用法
dynamic_cast可以获取目标对象的引用或指针:
T1 obj;
T2* pObj = dynamic_cast<T2*>(&obj);//转换为T2指针,失败返回NULL
T2& refObj = dynamic_cast<T2&>(obj);//转换为T2引用,失败抛出bad_cast异常
多态类型
在使用时需要注意:被转换对象obj的类型T1必须是多态类型,即T1必须公有继承自其它类,或者T1拥有虚函数(继承或自定义)。若T1为非多态类型,使用dynamic_cast会报编译错误。下面的例子说明了哪些类属于多态类型,哪些类不是:
//A为非多态类型
class A{
};
//B为多态类型
class B{
public: virtual ~B(){}
};
//D为多态类型
class D: public A{
};
//E为非多态类型
class E : private A{
};
//F为多态类型
class F : private B{
}
横向转型
在多态类型间转换,分为3种类型:
1.子类向基类的向上转型(Up Cast)
2.基类向子类的向下转型(Down Cast)
3.横向转型(Cross Cast)
向上转型是多态的基础,需不要借助任何特殊的方法,只需用将子类的指针或引用赋给基类的指针或引用即可,当然dynamic_cast也支持向上转型,而其总是肯定成功的。而对于向下转型和横向转型来讲,其实对于dynamic_cast并没有任何区别,它们都属于能力查询。为了理解方便,我们不妨把dynamic_cast视为cross cast:
class Shape {
public: virtual ~Shape();
virtual void draw() const = 0;
};
class Rollable {
public: virtual ~Rollable();
virtual void roll() = 0;
};
class Circle : public Shape, public Rollable {
void draw() const;
void roll();
};
class Square : public Shape {
void draw() const;
};
//横向转型失败
Shape *pShape1 = new Square();
Rollable *pRollable1 = dynamic_cast<Rollable*>(pShape2);//pRollable为NULL
//横向转型成功
Shape *pShape2 = new Circle();
Rollable *pRollable2 = dynamic_cast<Rollable*>(pShape2);//pRollable不为NULL
指针比较
接上面的例子,在我的机器上pShape2和pRollable2的值(所指向的地址)分别为:
pShape2: 0x0039A294, pRollable2:0x0039A290
说明dynamic_cast在进行转型的时候对不同多态类型设置了不同的偏移量。接下来的问题是
pRollable2 == pShape2
这个表达式应该返回什么呢?答案是:1,即指针比较相等。也许从C语言转到C++的朋友可能会感到困惑,因为在C语言中指针的比较只是值比较而已。显然,对于多态类型,C++编译器为==运算符做了更多的幕后工作来保证指针比较注重对象的同一性而非指针的值。至于实现细节涉及到C++对象模型,这是我还不甚熟悉的内容,故本文不再深入。
参考
相关推荐
本资源“例说 const_cast,reinterpret_cast,static_cast,dynamic_cast代码.rar”聚焦于四种主要的C++类型转换:const_cast、reinterpret_cast、static_cast和dynamic_cast。这四个关键字都是为了安全和高效地在...
### 标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast 在C++编程语言中,为了提高程序的可读性和安全性,C++标准库提供了多种类型的转换机制。其中,最常用的四种类型转换符包括:`...
C++提供了多种类型转换的方式,包括`static_cast`、`dynamic_cast`等,每种方式都有其特定的应用场景和特点。本文将重点介绍`static_cast`与`dynamic_cast`之间的区别及其应用场景。 #### `static_cast` `static_...
"dynamic_cast, static_cast 和 reinterpret_cast" 在 C++ 编程中,类型转换是一个非常重要的概念。我们经常需要将一个类型的对象转换为另一个类型,以满足不同的需求。但是,类型转换也可能会引发一些错误和问题。...
`dynamic_cast`和`static_cast`是两种不同的类型转换操作符,它们各自适用于不同的场景。本文将通过示例详细解释它们的使用方法,特别是它们在子类与基类之间的转换功能。 首先,我们来看`dynamic_cast`。`dynamic_...
C++中转型dynamic_cast.C++中转型dynamic_cast.C++中转型dynamic_cast.
本文将详细介绍四种主要的显式类型转换:`static_cast`、`dynamic_cast`、`const_cast`和`reinterpret_cast`。 首先,`static_cast`主要用于非多态类型的转换,它不提供运行时的类型检查。例如,当进行基类与子类...
标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast
dynamic_cast_benchmark 三种不同的dynamic_cast实现的性能比较请参阅我的博客文章: 汇编: git submodule initgit submodule updatemake./dynamic_cast_benchmark 目标编译器:clang版本13.0.0 以下是dynamic_cast...
C ++快速dynamic_cast <>替代 版权所有2013-2021 John Farrier Apache 2.0许可 概述 Priori是一个特殊的基类,当dynamic_cast<>本身已成为瓶颈时,它可以促进非常快速的dynamic_cast<>替代方案。 特别是在...
使用标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast。 const_cast,字面上理解就是去const属性。 static_cast,命名上理解是静态类型转换。如int转换成char。 dynamic_cast,...
在C++编程中,`static_cast`和`dynamic_cast`是两种主要的类型转换操作符,它们在处理类层次结构中的对象转换时起着至关重要的作用。本文将深入探讨这两种类型转换的区别,以及它们如何影响C++对象在内存中的占用。 ...
2.dynamic_cast提供安全的转换如果两个指针不存在继承关系转换会失败返回空指针,如果你提供一个错误的指针那样会发生内存访问异常,因为它会去比较两个类型的虚函数表。虚函数表的指针一般放在对象指针最开始的四字...
`dynamic_cast`是C++中的一种类型转换运算符,主要用于处理多态性,尤其是在继承层次结构中。在C++的面向对象编程中,它扮演着关键角色,允许开发者安全地在基类和派生类之间转换指针或引用。本文将深入探讨`dynamic...
C++提供了多种类型转换方式,包括`static_cast`、`dynamic_cast`、`const_cast`以及`reinterpret_cast`。本文将重点探讨`dynamic_cast`的使用方法、注意事项及其与其他类型转换符的对比,旨在为读者提供全面而深入的...
/*这是从网上摘下的样例,主要讲述了 dynamic_cast<> 的用法。*/ /* 作用:将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会依据基类指针是否真正指向继承类指针来做对应处理, 即会作一定的...
在C++编程中,`dynamic_cast`是一种运行时类型检查和转换工具,它允许程序员在多态性系统中安全地转换指针或引用。然而,`dynamic_cast`的使用可能会带来性能上的开销,特别是在大量对象转换的情况下。"Priori-快速...