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(); 这种调用最简单,因为不涉及虚函数,自然不会做类似上面的转换。
评论