根据上述的汇编代码,我们可以知道,在多态调用函数的时候,程序执行以下步骤:
1、寻址找到pObj1
2、由于C11重载了Test虚函数,所以*pObj1指向的就是C11的VTable的地址
3、调用pObj1->Test()时,程序通过Vptr(虚表的指针,对象的首地址),找到VTable,再根据偏移调用Test函数。
由于上述的多态调用过程是一个动态的过程(在运行时去“找”函数来调用),而不是编译完就直接把函数地址摆在那里了,所以被称作“动态联编”。
上面把多态的“动”和“静”的特点结合代码说了一遍,希望能说清楚了。
下面再验证一个类的虚表的问题,如果你对虚表已经很熟悉了,就不用再往下看了。
在很多书上都已经说明了C++的对象模型,这里只是做个验证。看看这段代码:
| class C1 ...{ public: virtual void Test() ...{ cout << "call C1 Test()" << endl; } }; class C11 : public C1 ...{ public: void Test() ...{ cout << "call C11 Test()" << endl; } }; class C12 : public C1 ...{ public: void Test() ...{ cout << "call C12 Test()" << endl; } }; |
| // 验证首地址 C11 obj110; C11 obj111; printf("obj110 的地址:%x ", &obj110); printf("obj111 的地址:%x ", &obj111); printf("obj110 虚表的地址:%x ", *(&obj110)); printf("obj111 虚表的地址:%x ", *(&obj111)); |