C++中动态绑定的实现机制
【问题】:动态绑定的实现机制?
C++编译器通过一个表格,在执行期间“间接”呼叫实际上欲绑定的函数(注意“间接”这个字眼)。这样的表格称为虚函数表(vtbl)。每一个“内含虚函数的类”,编译器都会为它做出一个虚函数表,表中的每一个元素都指向一个虚函数的地址。此外,编译器当然也会为类加上一项成员变量,是一个指向该虚函数表的指针(vptr)。
举例:
1 class Class1 2 { 3 public : 4 data1; 5 data2; 6 memfunc(); 7 virtual vfunc1(); 8 virtual vfunc2(); 9 virtual vfunc3(); 10 };
Class1 的实际对象在内存中实践占据这样的空间:
(这里我们可以看到在class1的对象内存里,并没有它的成员函数,它的成员函数在其他位置)
每一个有此类衍生出的对象,都有这么一个vptr。当我们通过这个对象调用虚函数时,事实上是通过vptr找到虚函数表,再找出虚函数的真正地址的。派生类会继承基类的虚函数(以及所有其他可以继承的成员),当我们在派生类中改写虚函数时,虚函数表就受到了影响:表中元素所指向的函数地址将不再是基类的函数地址,而是派生类的函数地址。
例子:
1 class Class2 : public Class1 2 { 3 public : 4 data3; 5 memfunc(); 6 virtual vfunc2(); 7 };
那么class2的对象的内存空间是这样的:
这样在派生类里调用没有重写的虚函数时,其实调用的是它的直接父类的对应虚函数,而调用已经重写的虚函数时就是调用它自己的了。