C++ 中的dynamic_cast 的真实示例
有人能给我一个真实世界的例子,说明需要dynamic_cast并且根本无法解决的情况吗?我能想到的例子通常可以通过双重调度来解决。
如果约束太强,那么通常使用dynamic_cast 的示例也很好。
我想看到真实的例子,而不是“它通常用于在类型树上和下类型之间进行转换”。
Can anybody give me a real world example of a case when dynamic_cast is needed and can't be worked around at all? Examples I can think of can generally be worked around with double dispatch.
If the constraint is too strong, an example where dynamic_cast is generally the way to go would also be nice.
I'd like to see real examples instead of "it's normally used to cast between types up and down a type tree".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
双重分派要求交互的类型对彼此的内部结构有深入的了解,因为它要求一个类调用另一个类的方法。当您无法修改类的内部结构,或者不希望破坏相关类的封装时,
dynamic_cast
可以使用。也就是说,双重调度对所涉及的类是侵入性的,而
dynamic_cast
在不了解类中的强制转换的情况下工作。如果您不知道将调用的目标方法重载,也可以使用
dynamic_cast
。有关示例,请参阅我昨天发布的这个问题。最后,双重调度也有它自己的麻烦
Double dispatch requires that the types that are interacting have intimate knowledge of each other's innards, as it requires that one class call methods on the other class.
dynamic_cast
works when you cannot modify the innards of a class, or do not wish to break encapsulation of the classes in question.That is, double dispatch is invasive on the classes involved, while
dynamic_cast
works without knowledge of the cast in the classes.You can also use
dynamic_cast
if you don't know the target method overload which will be invoked. For an example, see this question I posted yesterday.Finally, double dispatch does not come without it's own headaches
“根本无法解决”的约束太强了。任何 C++ 功能都可以用 C 来模拟。可以说,要解决该功能,您所要做的就是在 C++ 中使用该 C 代码。例如,MFC,一个起源于 1998 年语言标准化之前的库,提供并且仍然提供它自己的动态转换。
通常需要动态转换的一个示例是访问者模式,例如用于事件处理。访问的想法是集中动态转换,这样代码中就不再有无数的动态转换,而是只有一个:
该程序的输出是
Foo Fighter!
。如前所述,这已被简化。现实往往会更加混乱。并且有更多的代码。
干杯&嗯。
The constraint "can't be worked around at all" is too strong. Any C++ feature can be emulated in C. All you have to do to work around the feature, so to speak, is to use that C code in C++. For example, MFC, a library originating from the depths of time before the 1998 language standardization, offered and still offers its own kind of dynamic cast.
One example where you generally need dynamic casting is the visitor pattern, e.g. as used for event handling. The idea of visitation is to centralize the dynamic casting, so that instead of a zillion dynamic casts peppered throughout the code, there is a single one:
The output of this program is
Foo Fighter!
.As mentioned, this is simplified. Reality has a tendency to be a bit more messy. And with far more code.
Cheers & hth.
我个人用它来处理我的游戏引擎的某些部分。我有一个基本实体类,我从中派生出各种其他实体。我将它们转换为基类类型,以便可以轻松地将它们存储到链接列表中。当我想检查列表中的特定条目是否属于某个实体时,我将其动态转换为该类型。如果它返回 null,那么我就知道它不是。
I personally use it for working through certain parts of my game engine. I have a base entity class from which I derive various other entities from. I cast them to the base class type so I can store them easily into a linked list. When I want to check to see if a particular entry in my list is of a certain entity, I dynamic_cast it to that type. If it returns null, then I know it's not.
假设我们有一个库,我们正在使用它来派生一些类型:
当我们派生我们的类型时,我们有一些对所有情况都是通用的东西:
现在,正如我们所使用我们的库,并且有一个采用类型 A& 的回调。 (或 B& 或 C&)
并假设在该函数中它期望多态行为,但我们需要访问一些 CommonStuff:
由于 A 和 CommonStuff 之间没有直接关联,因此我们不能使用 static_cast,
reinterpret_cast
显然不是正确的选择,因为它会引入切片。这里唯一的选项是dyanmic_cast
。现在,对此持保留态度,因为这是可以解决的。
Let's say we have a library that we're using that is meant for us to derive some types from:
And when we're deriving our types, we have some things that are common to all of our cases:
Now, as we're working with our library, and there is a callback that takes type A& (or B& or C&)
And assume in that function it expects polymorhpic behavior, but we need to access some of our CommonStuff:
Since there's no direct correlation between A and CommonStuff, we cannot use
static_cast
,reinterpret_cast
is obviously not the right choice as it will introduce slicing. The only option here isdyanmic_cast
.Now, take this with a grain of salt, because this could be worked around.
您通常可以通过向 A 添加虚函数来替换dynamic_cast(...)。但是,如果 A 是来自第三方库的类,那么您无法更改它,因此您无法添加虚函数对它起作用。所以你可能必须使用dynamic_cast。
You can often replace dynamic_cast<A*>(...) by adding a virtual function to A. However, if A is a class from a third party library then you can't change it so you can't add a virtual function to it. So you may have to use dynamic_cast.