虚函数表与动态绑定

(你可能会有一个疑问:编译器是如何实现虚函数的呢?)

虚表:

  • 每个多态类有一个虚表(virtual table)
  • 虚表中有当前类的各个虚函数的入口地址
  • 每个对象有一个指向当前类的虚表的指针(虚指针vptr)


动态绑定的实现:

  • 构造函数中为对象的虚指针赋值
  • 通过多态类型的指针或引用调用成员函数时,通过虚指针找到虚表,进而找到所调用的虚函数的入口地址
  • 通过该入口地址调用虚函数


样例:(图表与程序对应)

虚函数表与动态绑定_第1张图片

#include
class Base
{
	public:
		virtual void F()  {  printf("F1\n");  }
		virtual void G()  {  printf("G1\n");  }
	private:
		int i;
};
class Derived:  public Base
{
	public:
		virtual void F()  {  printf("F2\n");  }
		virtual void H()  {  printf("H2\n");  }		//新增的虚函数
	private:
		int j;
};
int main(void)
{
	Base p;
	Derived q;
	printf("%d %d\n", sizeof(p), sizeof(q));		//输出结果:8 12,因为有一个隐藏的指向虚函数表的指针
	return 0;
}

你可能感兴趣的:(C++)