class A { virtual void fun(){printf("this is a's private fun\n");} }; class B { public: virtual void fun(){printf("this is b's public fun\n");} }; int _tmain(int argc, _TCHAR* argv[]) { A* pa = new A; B* pb=(B*)pa; pb->fun(); return 0; } 对于pb->fun()编译器首先检查pb的类型为B,于是到B的定义里找fun发现是virtual。于是做了如下转换: typedef void (*pFoo)(); pFoo(*(int*)(*((int*)pb)))(); 这样起始调用的是A中的fun。 如果B的fun为虚,而A的fun非虚,编译器同样会做上面的转换,当然运行的时候就报内存访问违规了。原因很简单,A中并没有虚函数,自然不会有虚表。 如果B的fun是非virtual,编译器就编译器就直接调用了B中的fun: B::fun(); 这种调用最简单,因为不涉及虚函数,自然不会做类似上面的转换。

评论