我对C++中的RTTI机制有一些疑惑。RTTI是如何工作的?
假设中有A类和从A继承现在考虑下面的代码B类:
B* b = new B();
A* a = dynamic_cast<A*>(b);
我知道,多态类的虚拟方法有虚表和vptr的的,但我认为指针只提供有关虚拟功能的信息。程序如何在运行时知道b的类型,使用vptr和vtables?
我对C++中的RTTI机制有一些疑惑。RTTI是如何工作的?
假设中有A类和从A继承现在考虑下面的代码B类:
B* b = new B();
A* a = dynamic_cast<A*>(b);
我知道,多态类的虚拟方法有虚表和vptr的的,但我认为指针只提供有关虚拟功能的信息。程序如何在运行时知道b的类型,使用vptr和vtables?
想象一下,你有
struct B {
virtual doSth() {
cout << "hello";
}
};
struct A : public B {
doSth() {
cout << "hello world";
}
};
现在假设A :: doSth()是0x0f43和B :: doSth()是在0x0a41
然后dynamic_cast的(B)可以作为(伪实施-code)
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。不,它不会编译(或不应该)。见http://stackoverflow.com/questions/4131091/dynamic-cast-from-void –
“我认为指针只能提供有关虚拟功能的信息” - 你为什么这么想? vptr指向所有动态类型信息 - vtable,以及RTTI需要的任何信息。 –
@MikeSeymour除了vtable,还有什么指向? –
无论支持RTTI需要特定于实现的元数据。恐怕我不知道它是如何实施的,但我相信谷歌可以告诉你,如果你有兴趣。 –