动态铸造有哪些“好用”的例子?

What are some 'good use' examples of dynamic casting?

提问人:OysterD 提问时间:8/26/2008 最后编辑:sk8foretherOysterD 更新时间:9/20/2017 访问量:26850

问:

我们经常听到/读到应该避免动态投射。我想知道,根据你的说法,什么是“好用”的例子?

编辑:

是的,我知道另一个线程:确实是在阅读那里的第一个答案之一时,我问了我的问题!

C Casting (C++铸造) RTTI 动态铸造

评论

12赞 bradtgmurray 7/8/2009
这个问题的标题与描述不完全匹配。

答:

0赞 DrPizza 8/26/2008 #1

我目前的玩具项目使用了两次dynamic_cast;一次是解决C++中缺少多重调度的问题(这是一个访客式系统,可以使用多重调度而不是dynamic_casts),一次是针对特定子类型的特殊情况。

在我看来,这两者都是可以接受的,尽管前者至少源于语言缺陷。事实上,我认为这可能是一种常见的情况;大多数dynamic_casts(以及许多“设计模式”)都是针对特定语言缺陷的解决方法,而不是针对特定语言缺陷的东西。

0赞 Eclipse 9/20/2008 #2

当通过 C 接口向对象公开句柄时,它可以用于一些运行时类型安全。让所有公开的类都继承自公共基类。接受函数的句柄时,首先强制转换为基类,然后动态强制转换为预期的类。如果它们传入了无意义的句柄,则当运行时找不到 rtti 时,将出现异常。如果它们传入了错误类型的有效句柄,则会获得一个 NULL 指针,并可以引发自己的异常。如果他们传入了正确的指针,你就可以开始了。 这并不是万无一失的,但它肯定比从句柄直接重新解释强制转换更能捕获对库的错误调用,并等到某些数据在传递错误的句柄时神秘地损坏。

1赞 rlerallut 9/23/2008 #3

这是我经常做的事情,它并不漂亮,但它简单而有用。

我经常使用实现接口的模板容器, 想象一下这样的事情

template<class T>
class MyVector : public ContainerInterface
...

其中 ContainerInterface 有基本有用的东西,但仅此而已。如果我想在不公开模板实现的情况下对整数向量使用特定算法,那么接受接口对象并将其dynamic_cast到实现中的 MyVector 很有用。例:

// function prototype (public API, in the header file)
void ProcessVector( ContainerInterface& vecIfce );

// function implementation (private, in the .cpp file)
void ProcessVector( ContainerInterface& vecIfce)
{
    MyVector<int>& vecInt = dynamic_cast<MyVector<int> >(vecIfce); 
    // the cast throws bad_cast in case of error but you could use a
    // more complex method to choose which low-level implementation
    // to use, basically rolling by hand your own polymorphism.

    // Process a vector of integers
    ...
}

我可以向 ContainerInterface 添加一个 Process() 方法,该方法将进行多态解析,这将是一个更好的 OOP 方法,但我有时更喜欢这样做。当你有简单的容器,大量的算法,并且你想隐藏你的实现时,dynamic_cast提供了一个简单而丑陋的解决方案。

您还可以查看双重调度技术。

HTH型

0赞 Proviance 11/20/2008 #4

好吧,使用 C# 中的扩展方法会很好。

例如,假设我有一个对象列表,我想从中获取所有 ID 的列表。我可以逐个浏览它们并将它们拉出,但我想将该代码分割出来以供重用。

所以像这样的东西

List<myObject> myObjectList = getMyObjects();

List<string> ids = myObjectList.PropertyList("id");

会很酷,除了在扩展方法上,你不会知道要进来的类型。

所以

public static List<string> PropertyList(this object objList, string propName) {
    var genList = (objList.GetType())objList;
}

太棒了。

9赞 Mark Ransom 11/20/2008 #5

这个最近的帖子给出了一个例子,说明它在哪些方面派上用场。有一个基 Shape 类以及从它派生的类 Circle 和 Rectangle。在测试相等性时,很明显,一个圆不能等于一个矩形,试图比较它们将是一场灾难。在循环访问指向 Shapes 的指针集合时,dynamic_cast执行双重任务,告诉您形状是否具有可比性,并为您提供进行比较的适当对象。

矢量迭代器不可取消引用

0赞 Zsolt Szatmari 3/29/2014 #6

它非常有用,然而,大多数时候它有用了:如果完成工作最简单的方法是做一个dynamic_cast,这往往是糟糕的OO设计的症状,这反过来又可能导致未来以不可预见的方式出现麻烦。