今天读了《深入浅出MFC》的类和对象的大解剖这一章节,终于对虚函数有了进一步的了解:
“C++编译器通过一张表,在执行期间接调用实际上预绑定的函数”。首先这张表是虚函数表,有一个指针vptr指向它,这张表是每个包含虚函数的类都会为其创建的,表中每一个表项都指向一个虚函数的地址。
比如建立了ClassTest类
class ClassTest
{
int m_data1;
int m_data2;
void mem_funtion();
virtual vfun1();
virtual vfun2();
virtual vfun3();
}
而实际上在内存中该类的实例所占的空间如下:
PS:C++类成员函数,可以看做是普通的C语言函数,并由编译器隐蔽的加上了一个this指针,所以在内存区域看不到任何有关成员函数 的信息。
每一个由此类派生出来的类,也会有虚函数表,并且我们对该对象进行调用,是通过查找虚函数表去找函数的入口地址。派生类也会继承虚函数表,如果派生类中改写虚函数,机会更改虚函数表,表中元素所指的函数的地址不在是基类的地址,而是派生类的函数地址。
class ClassTest2 : ClassTest
{
int m_data3;
void mem_funtion();
virtual vfun2();
}
在内存中的信息如下图:
所以指向ClassTest的对象调用的是ClassTest::Vfun2(); 指向ClassTest2对象调用vfun2是ClassTest2::vfun2()