【问题标题】:How does RTTI work?RTTI 是如何工作的?
【发布时间】:2014-09-08 11:15:06
【问题描述】:

我对 C++ 中的 RTTI 机制有些困惑。

假设有继承自 A 的 A 类和 B 类。现在考虑以下代码:

B* b = new B();
A* a = dynamic_cast<A*>(b);

我知道具有虚方法的多态类具有虚表和 vptr,但我认为指针仅提供有关虚函数的信息。程序如何在运行时使用 vptr 和 vtables 知道 b 的类型?

【问题讨论】:

  • “我认为指针只提供有关虚函数的信息” - 你为什么这么认为? vptr 指向所有动态类型信息 - vtable,以及 RTTI 所需的任何内容。
  • @MikeSeymour 除了 vtable,还有什么指向?
  • 支持 RTTI 需要任何特定于实现的元数据。恐怕我不知道它通常是如何实现的,但如果你有兴趣,我相信谷歌会告诉你。
  • This 可能有帮助,也可能没有帮助。

标签: c++ polymorphism rtti


【解决方案1】:

假设你有

struct B {
    virtual doSth() {
        cout << "hello";
    }
};
struct A : public B {
    doSth() {
        cout << "hello world";
    }
};

现在假设 A::doSth() 在 0x0f43 并且 B::doSth() 在 0x0a41

那么dynamic_cast(b)可以实现为(伪代码)

if ( (address pointed to by b::doSth()) == 0x0f43 ) {
    // cast is OK
} else { // (address pointed to by b::doSth()) == 0x0a41
    // not possible to cast
}

所以你真的只需要 b 持有一个指向正确的 doSth() 方法的指针来知道它的真实类型

【讨论】:

  • 我假设有一个隐含的行说类似: void *b = (void *)new B() 在那里。如果是这样,那 b 是不是可能是一些完全不相关的东西,比如一个字节数组,恰好在正确的偏移量处有一个 0x0f43?
  • 如果 b 是字节数组,dynamic_cast 甚至不会编译,因为 b 不是 B 类型。
  • @Moby Dick。不,它不编译(或不应该编译)。见stackoverflow.com/questions/4131091/dynamic-cast-from-void
猜你喜欢
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-24
  • 2016-11-13
  • 2017-10-11
  • 2021-10-13
  • 2011-02-24
相关资源
最近更新 更多