提问人:OysterD 提问时间:8/26/2008 最后编辑:sk8foretherOysterD 更新时间:9/20/2017 访问量:26850
动态铸造有哪些“好用”的例子?
What are some 'good use' examples of dynamic casting?
答:
我目前的玩具项目使用了两次dynamic_cast;一次是解决C++中缺少多重调度的问题(这是一个访客式系统,可以使用多重调度而不是dynamic_casts),一次是针对特定子类型的特殊情况。
在我看来,这两者都是可以接受的,尽管前者至少源于语言缺陷。事实上,我认为这可能是一种常见的情况;大多数dynamic_casts(以及许多“设计模式”)都是针对特定语言缺陷的解决方法,而不是针对特定语言缺陷的东西。
当通过 C 接口向对象公开句柄时,它可以用于一些运行时类型安全。让所有公开的类都继承自公共基类。接受函数的句柄时,首先强制转换为基类,然后动态强制转换为预期的类。如果它们传入了无意义的句柄,则当运行时找不到 rtti 时,将出现异常。如果它们传入了错误类型的有效句柄,则会获得一个 NULL 指针,并可以引发自己的异常。如果他们传入了正确的指针,你就可以开始了。 这并不是万无一失的,但它肯定比从句柄直接重新解释强制转换更能捕获对库的错误调用,并等到某些数据在传递错误的句柄时神秘地损坏。
这是我经常做的事情,它并不漂亮,但它简单而有用。
我经常使用实现接口的模板容器, 想象一下这样的事情
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型
好吧,使用 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;
}
太棒了。
这个最近的帖子给出了一个例子,说明它在哪些方面派上用场。有一个基 Shape 类以及从它派生的类 Circle 和 Rectangle。在测试相等性时,很明显,一个圆不能等于一个矩形,试图比较它们将是一场灾难。在循环访问指向 Shapes 的指针集合时,dynamic_cast执行双重任务,告诉您形状是否具有可比性,并为您提供进行比较的适当对象。
它非常有用,然而,大多数时候它太有用了:如果完成工作最简单的方法是做一个dynamic_cast,这往往是糟糕的OO设计的症状,这反过来又可能导致未来以不可预见的方式出现麻烦。
评论