使用dynamic_cast而不是常规多态性的优点是什么? [英] What is the advantage of using dynamic_cast instead of conventional polymorphism?

查看:134
本文介绍了使用dynamic_cast而不是常规多态性的优点是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们可以使用多态性(继承+虚拟函数),以便在一个共同的基本类型下泛化不同的类型,然后引用不同的对象,就像它们是相同的类型。

We can use Polymorphism (inheritance + virtual functions) in order to generalize different types under a common base-type, and then refer to different objects as if they were of the same type.

使用 dynamic_cast 看起来是完全相反的方法,因为我们实质上是在确定对象的具体类型之前决定我们要采取什么行动。

Using dynamic_cast appears to be the exact opposite approach, as in essence we are checking the specific type of an object before deciding what action we want to take.

对于使用常规多态性无法实现的任何已知示例,与使用 dynamic_cast

Is there any known example for something that cannot be implemented with conventional polymorphism as easily as it is implemented with dynamic_cast?

推荐答案

每当你发现自己想要一个成员函数像基础类中的IsConcreteX(编辑:一个像ConcreteX * GetConcreteX的函数),你基本上实现自己的 dynamic_cast 。例如:

Whenever you find yourself wanting a member function like "IsConcreteX" in a base class (edit: or, more precisely, a function like "ConcreteX *GetConcreteX"), you are basically implementing your own dynamic_cast. For example:

class Movie
{
    // ...
    virtual bool IsActionMovie() const = 0; 
};

class ActionMovie : public Movie
{
    // ...
    virtual bool IsActionMovie() const { return true; }
};

class ComedyMovie : public Movie
{
    // ...
    virtual bool IsActionMovie() const { return false; }
};


void f(Movie const &movie)
{
    if (movie.IsActionMovie())
    {
        // ...
    }
}

$ c> dynamic_cast ,但是仔细检查,你很快就会意识到,除了evil dynamic_cast 不再出现在你的代码中(如果你没有使用一个古老的编译器不实现 dynamic_cast !:))。更糟糕的是 - 自写动态转换方法是冗长,容易出错和重复的,而 dynamic_cast 将正常工作,没有任何额外的代码在类定义。

This may look cleaner than a dynamic_cast, but on closer inspection, you'll soon realise that you've not gained anything except for the fact that the "evil" dynamic_cast no longer appears in your code (provided you're not using an ancient compiler which doesn't implement dynamic_cast! :)). It's even worse - the "self-written dynamic cast" approach is verbose, error-prone and repetitve, while dynamic_cast will work just fine with no additional code whatsoever in the class definitions.

因此,真正的问题应该是:是否有一个基类知道一个具体的派生类。答案是:通常不会,但你会毫无疑问地遇到这样的情况。

So the real question should be whether there are situations where it makes sense that a base class knows about a concrete derived class. The answer is: usually it doesn't, but you will doubtlessly encounter such situations.

以抽象的方式思考你的软件的一个组件,一部分(A)到另一部分(B)。这些对象是 Class1 Class2 类型, Class2 is-a Class1

Think, in very abstract terms, about a component of your software which transmits objects from one part (A) to another (B). Those objects are of type Class1 or Class2, with Class2 is-a Class1.

Class1
  ^
  |
  |
Class2


A - - - - - - - -> B
    (objects)

B,但是只有 Class2 。 B可以是系统的完全不同的部分,由不同的人或遗留代码写。在这种情况下,您想要重复使用A到B通信而不进行任何修改,您也可能不能修改B。因此,明确地询问是否在线的另一端处理 Class1 Class2 对象。

B, however, has some special handling only for Class2. B may be a completely different part of the system, written by different people, or legacy code. In this case, you want to reuse the A-to-B communication without any modification, and you may not be in a position to modify B, either. It may therefore make sense to explicitly ask whether you are dealing with Class1 or Class2 objects at the other end of the line.

void receiveDataInB(Class1 &object)
{
    normalHandlingForClass1AndAnySubclass(object);
    if (typeid(object) == typeid(Class2))
    {
        additionalSpecialHandlingForClass2(dynamic_cast<Class2 &>(object));
    }
}

这里是一个不使用 typeid

void receiveDataInB(Class1 &object)
{
    normalHandlingForClass1AndAnySubclass(object);
    Class2 *ptr = dynamic_cast<Class2 *>(&object);
    if (ptr != 0)
    {
        additionalSpecialHandlingForClass2(*ptr);
    }
}

Class2 不是叶类(即如果可能有进一步派生的类)。

This might be preferable if Class2 is not a leaf class (i.e. if there may be classes further deriving from it).

最后,无论你是从一开始就设计一个整个系统的所有部分,或者在稍后阶段修改或调整它的一部分。但是,如果你发现自己遇到了像上面这样的问题,你可以来欣赏 dynamic_cast 作为正确的工作在正确的情况下正确的工具。

In the end, it often comes down to whether you are designing a whole system with all its parts from the beginning or have to modify or adapt parts of it at a later stage. But if you ever find yourself confronted with a problem like the one above, you may come to appreciate dynamic_cast as the right tool for the right job in the right situation.

这篇关于使用dynamic_cast而不是常规多态性的优点是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆