有没有人能给我一个现实世界中需要使用dynamic_cast并且不能完全通过双重分派来解决的案例?我能想到的例子通常都可以通过双重分派来解决。
如果限制太强了,一个通常需要使用dynamic_cast的示例也会很好。
我想看到真正的例子,而不是“它通常用于类型树上下转换的强制类型转换”。
有没有人能给我一个现实世界中需要使用dynamic_cast并且不能完全通过双重分派来解决的案例?我能想到的例子通常都可以通过双重分派来解决。
如果限制太强了,一个通常需要使用dynamic_cast的示例也会很好。
我想看到真正的例子,而不是“它通常用于类型树上下转换的强制类型转换”。
dynamic_cast
可起作用。dynamic_cast
在不知道类中转换的情况下工作。dynamic_cast
。例如,请参见我昨天发布的这个问题。#include <stdio.h>
void say( char const s[] ) { printf( "%s\n", s ); }
struct Event
{
struct Handler
{
virtual void onEvent( Event& ) = 0;
};
virtual void dispatchTo( Handler& aHandler )
{
aHandler.onEvent( *this );
}
template< class SpecificEvent >
static void dispatch( SpecificEvent& e, Handler& aHandler )
{
typedef typename SpecificEvent::Handler SpecificHandler;
// The single dynamic cast:
if( SpecificHandler* p = dynamic_cast<SpecificHandler*>( &aHandler ) )
{
p->onEvent( e );
}
else
{
e.Event::dispatchTo( aHandler );
}
}
};
struct FooEvent
: Event
{
struct Handler
{
virtual void onEvent( FooEvent& ) = 0;
};
virtual void dispatchTo( Event::Handler& aHandler )
{
dispatch( *this, aHandler );
}
};
struct Plane
: Event::Handler
{
virtual void onEvent( Event& ) { say( "An event!" ); }
};
struct Fighter
: Plane
, FooEvent::Handler // Comment out this line to get "An event!".
{
virtual void onEvent( FooEvent& ) { say( "Foo Fighter!" ); }
};
void doThingsTo( Plane& aPlane )
{
FooEvent().dispatchTo( aPlane );
}
int main()
{
Fighter plane;
doThingsTo( plane );
}
这个程序的输出是Foo Fighter!
。
正如所提到的,这只是简化版。现实往往会更加混乱,而且代码也更多。
祝好运!
class A {};
class B : public A {};
class C : public B {};
当我们派生类型时,有一些东西是所有情况都共有的:
class CommonStuff {};
class D : public CommonStuff, public C {};
现在,我们正在使用我们的库,并且有一个回调函数需要传入类型A&(或B&或C&)
void some_func(A& obj);
假设该函数期望具有多态行为,但我们需要访问一些共同的东西:
void some_func(A& obj)
{
CommonStuff& comn = dynamic_cast<CommonStuff&>(obj);
}
由于A和CommonStuff之间没有直接的关联,我们不能使用static_cast
,显然reinterpret_cast
也不是正确的选择,因为它会引入切片。在这里唯一的选择是dynamic_cast
。
现在,需要注意的是,这可以通过一些方法解决。
reinterpret_cast
仍然不合适...它不能像static_cast
那样正确地转换指向基类型的指针。 - Dennis Zickefoose我个人用它来处理游戏引擎的某些部分。我有一个基础实体类,从中派生出各种其他实体。我将它们转换为基类类型,以便可以轻松地将它们存储到链表中。当我想要检查列表中特定条目是否属于某个实体时,我将其 dynamic_cast 到该类型。如果返回 null,则知道它不是。
dynamic_cast
的论据。(在游戏引擎中使用链表?!) - Billy ONeal通常情况下,您可以通过向A添加虚函数来替换dynamic_cast<A*>(...)。但是,如果A是来自第三方库的类,则无法更改它,因此无法向其添加虚函数。因此,您可能需要使用dynamic_cast。
dynamic_cast
?旧的编译器执行它的速度非常慢,但现在几乎所有人都将其实现为简单的 vtbl 指针比较。 - Billy ONeal