虚函数表的证明
虚函数表定义
昨天说到了虚函数表有的人可能会疑问,今天来证明一下,并且说说多态到低怎么实现的。
虚函数表他是通过一块连续的内存来存储虚函数地址的,其实内存本来就是连续的。这张表解决了虚函数重写的问题。在有虚函数对象的实例中都会对应一个虚函数表,像一张地图,指向了实际调用的虚函数。接下来我就来证明一下虚函数表:
证明:
class annimal{
public:
annimal()
{
cout << "hello world\n";
}
virtual void CanDo()
{
cout << "我会动\n";
}
virtual void fun1()
{
cout << "会喝水\n";
}
};
class WuYa :public annimal
{
public:
WuYa()
{
cout << "我是乌鸦\n";
}
virtual void CanDo()
{
cout << "会飞\n";
}
virtual void fun1()
{
cout << "会从瓶子里喝水\n";
}
};
class Dog :public annimal
{
public:
Dog()
{
cout << "this is dog\n";
}
virtual void CanDo()
{
cout << "会吃屎\n";
}
virtual void fun1()
{
cout << "会跑\n";
}
virtual void CandoElse()
{
cout << "会咬人\n";
}
};
void dododo(annimal *dog1)
{
dog1->CanDo();
}
int main()
{
WuYa *m_wuya = new WuYa();
dododo(m_wuya);
Dog *m_dog = new Dog();
dododo(m_dog);
system("pause");
}
总结:看到没编译器显示的_vfptr就是指向虚函数表的指针,其中vfptr[0]就是WuYa::CanDo(),vfptr[1]就是WuYa::fun1();虽然用父类接管了子类的对象(WuYa),但是传过来之后,调用dog1->CanDo();语句的时候并没有执行父类的CanDo();而是调用了它实际指向的对象。有兴趣的可以自己调试另外的对象。其实也就是动态联编PK静态联编。静态联编是编译时候就决定了调用,而动态联编只有在程序运行时才能决定调用(先获取对象的地址,而一般每一次程序运行时对象的地址都不相同)。所以在效率上就比普通函数低。所以根据需要加virtual。