我有一个关于dynamic_cast运算符的非常简单的问题.我知道这用于运行时类型识别,即在运行时了解对象类型.但是根据您的编程经验,您能否提供一个真实场景,您必须使用此运算符?没有使用它有什么困难?
Bjo*_*rnD 49
玩具示例
诺亚方舟将作为不同类型动物的容器.由于方舟本身并没有在意猴子,企鹅,和蚊子之间的区别,你定义一个类Animal,派生类Monkey,Penguin以及Mosquito由它,他们每个人存储为一个Animal在方舟.
一旦洪水结束,诺亚想要将动物分布在地球上,并将它们分配到它们所属的地方,因此需要更多关于存放在他的方舟中的通用动物的知识.作为一个例子,他现在可以尝试将dynamic_cast<>每只动物设置为a Penguin,以便找出哪些动物是企鹅在南极释放,哪些不是.
真实的例子
我们实现了一个事件监视框架,其中应用程序将运行时生成的事件存储在列表中.事件监视器会去通过这个列表,并检查他们有兴趣在这些特定的事件.事件类型是操作系统级的东西,如SYSCALL,FUNCTIONCALL和INTERRUPT.
在这里,我们将所有特定事件存储在一个通用的Event实例列表中.然后,监视器将遍历此列表并将dynamic_cast<>他们看到的事件迭代到他们感兴趣的那些类型.所有其他(引发异常的那些)将被忽略.
问题:为什么不能为每种事件类型单独列出一个列表?
答:您可以这样做,但它会使系统扩展新事件以及新监视器(聚合多个事件类型)更难,因为每个人都需要知道要检查的相应列表.
Ker*_* SB 10
一个典型的用例是访问者模式:
struct Element
{
virtual ~Element() { }
void accept(Visitor & v)
{
v.visit(this);
}
};
struct Visitor
{
virtual void visit(Element * e) = 0;
virtual ~Visitor() { }
};
struct RedElement : Element { };
struct BlueElement : Element { };
struct FifthElement : Element { };
struct MyVisitor : Visitor
{
virtual void visit(Element * e)
{
if (RedElement * p = dynamic_cast<RedElement*>(e))
{
// do things specific to Red
}
else if (BlueElement * p = dynamic_cast<BlueElement*>(e))
{
// do things specific to Blue
}
else
{
// error: visitor doesn't know what to do with this element
}
}
};
Run Code Online (Sandbox Code Playgroud)
现在,如果你有一些Element & e;,你可以MyVisitor v;说和说e.accept(v).
关键设计功能是,如果您修改Element层次结构,则只需编辑访问者.该模式仍然相当复杂,只有在您拥有非常稳定的类层次结构时才推荐使用Element.
| 归档时间: |
|
| 查看次数: |
4024 次 |
| 最近记录: |