dynamic_cast通常如何实现?

时间:2010-07-23 02:18:33

标签: c++ dynamic-cast

类型检查仅仅是整数比较吗?或者有一个GetTypeId虚函数来区分哪个会使它成为整数比较?

(只是不希望事物成为类名的字符串比较)

编辑:我的意思是,如果我经常期待错误的类型,那么使用类似的东西是否合理:

struct Token
{
    enum {
        AND,
        OR,
        IF
    };
    virtual std::size_t GetTokenId() = 0;
};

struct AndToken : public Token
{
    std::size_t GetTokenId() { return AND; }
};

使用GetTokenId成员而不是依赖dynamic_cast

4 个答案:

答案 0 :(得分:6)

dynamic_cast的功能远远超出了简单的类型检查。如果它只是一种类型检查,它将很容易实现(就像你在原帖中所拥有的那样)。

除了类型检查之外,dynamic_cast还可以执行对void *的转换以及分层交叉转换。这些类型的强制转换在概念上需要一些能够在两个方向(向上和向下)遍历类层次结构。支持这种强制转换所需的数据结构比纯粹的标量类型id更复杂。 dynamic_cast正在使用的信息是RTTI的一部分。

试图在这里描述它会适得其反。我曾经有一个很好的链接,描述了RTTI的一个可能的实现...将尝试找到它。

答案 1 :(得分:1)

在一些原始编译器中,你是正确的,他们使用字符串比较。

因此,dynamic_cast<>非常慢(相对来说),因为类层次结构遍历/向下遍历层次结构链需要与类名称进行字符串比较。

这导致很多人开发自己的铸造技术。这几乎总是徒劳无功,因为它需要正确地对每个类进行注释,并且当出现问题时几乎不可能追踪错误。

但这也是古老的历史。

我不确定它现在是如何完成的,但它肯定不涉及字符串比较。自己动手也是一个坏主意(永远不要做编译器已经在做的工作)。您所做的任何尝试都不会像编译器那样快速或准确,请记住,多年的开发已经尽可能快地使编译器代码(并且它始终是正确的)。

答案 2 :(得分:1)

我不知道确切的实现,但是我知道如何做到这一点:

Derived*Base*的转换可以在编译时完成。两个不相关的polimorphic类型之间的转换也可以在编译时完成(只返回NULL)。

Base*Derived*的转换需要在运行时完成,因为可能有多个派生类。可以使用绑定到对象的虚方法表来完成动态类型的标识(这就是它需要多态类的原因)。

此VMT可能包含有关基类及其数据偏移的额外信息。当涉及多个继承时,这些数据偏移是相关的,并且被添加到源指针以使其指向正确的位置。

如果在基类中未找到所需类型,dynamic_cast将返回null。

答案 3 :(得分:0)

编译器无法识别您可能拥有的其他信息并将其粘贴在dynamic_cast中。如果您知道有关代码的某些不变量,并且您可以证明您的手动转换机制更快,请自行完成。在这种情况下如何实现dynamic_cast并不重要。