什么是动态铸造的“好用”例子?

时间:2008-08-26 13:49:48

标签: c++ casting rtti dynamic-cast

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

编辑:

是的,我知道that other thread:确实在阅读那里的第一个答案时,我问了我的问题!

6 个答案:

答案 0 :(得分:9)

这个最近的帖子给出了一个方便的例子。有一个基础的Shape类和从它派生的Circle和Rectangle类。在测试相等性时,很明显Circle不能等于Rectangle,尝试比较它们将是一场灾难。在迭代指向Shapes的指针集合时,dynamic_cast会执行双重任务,告诉您形状是否具有可比性,并为您提供正确的对象以进行比较。

Vector iterator not dereferencable

答案 1 :(得分:1)

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

我经常使用实现接口的模板容器, 想象像

这样的东西
template<class T>
class MyVector : public ContainerInterface
...

ContainerInterface有基本有用的东西,但就是这样。如果我想在整数向量上使用特定的算法而不暴露我的模板实现,那么在实现中接受接口对象并将其动态广播到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
    ...
}

我可以将一个Process()方法添加到可以多态解析的ContainerInterface中,这将是一个更好的OOP方法,但我有时更喜欢这样做。当你拥有简单的容器,许多算法并希望隐藏你的实现时,dynamic_cast提供了一个简单而丑陋的解决方案。

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

HTH

答案 2 :(得分:0)

我目前的玩具项目使用了dynamic_cast两次;曾经解决过C ++中缺少多次调度的问题(它是一个访问者风格的系统,可以使用多个调度而不是dynamic_casts),一次是特殊情况下的特定子类型。

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

答案 3 :(得分:0)

当通过C接口向对象公开句柄时,它可用于一些运行时类型安全性。让所有公开的类继承自公共基类。当接受函数的句柄时,首先强制转换为基类,然后动态转换为您期望的类。如果他们传入一个非敏感的句柄,当运行时找不到rtti时,你会得到一个例外。如果它们传入了错误类型的有效句柄,则会得到一个NULL指针并且可以抛出自己的异常。如果他们传递了正确的指针,那么你很高兴。 这不是万无一失的,但是对于错误调用库来说肯定比从句柄中直接重新解释一样,并等到一些数据在你传递错误的句柄时被神秘地破坏了。

答案 4 :(得分:0)

使用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;
}

会很棒。

答案 5 :(得分:0)

这是非常有用的,但是,大多数情况下它有用:如果要完成工作,最简单的方法是做一个dynamic_cast,它通常不是一个坏的症状OO设计,反过来可能会以不可预见的方式导致未来的麻烦。