原作者:zeeshan amjad原文链接:http://www.codeproject.com/atl/atl_underthehood_2.asp介绍 在本系列的教程中,我要讨论一些atl的内部工作方式以及它所使用的技术,这是本系列的第二篇文章. 现在让我们来探究一些虚函数背后更加有趣的资料.为了与上文保持一致,在本文的讨论中我将使用相同的顺序,程序的序号从20开始. 让我们看看下面这个程序:程序20.#include <iostream>using namespace std;class base {public: virtual void fun() { cout << "base::fun" << endl; } void show() { fun(); }};class drive : public base {public: virtual void fun() { cout << "drive::fun" << endl; }};int main() { drive d; d.show(); return 0;} 程序的输出为:drive::fun 这个程序清楚地示范了基类的函数是如何调用派生类的虚函数的.这一技术被用于不同的框架中,例如mfc与设计模式(比如template design pattern).现在你可以修改一下这个程序来看看它的行为,我将要在基类的构造函数中调用虚函数,而不是普通的成员函数.程序21.#include <iostream>using namespace std;class base {public: base() { fun(); } virtual void fun() { cout << "base::fun" << endl; }};class drive : public base {public: virtual void fun() { cout << "drive::fun" << endl; }};int main() { drive d; return 0;} 程序的输出为:base::fun 这个程序表明,我们不能在基类的构造函数中调用派生类的虚函数.好了,那就让我们来看看着布幔之下到底做了什么.我将会把这些构造函数之中的指针值打印出来,为了简便起见,我移除了类中其它的函数.程序22.#include <iostream>using namespace std;class base {public: base() { cout << "in base" << endl; cout << "this pointer = " << (int*)this << endl; cout << endl; }virtual void f() { cout << "base::f" << endl; }};class drive : public base {public: drive() { cout << "in drive" << endl; cout << "this pointer = " << (int*)this << endl; cout << endl; }virtual void f() { cout << "drive::f" << endl; }};int main() { drive d; cout << "in main" << endl; cout << (int*)&d << endl; return 0;} 程序的输出为:in basethis pointer = 0012ff7cin drivethis pointer = 0012ff7cin main0012ff7c 这就表示,整个内存位置中,只有一个对象的存在.那么就让我们把这个指针指向的值打印出来,也就是虚函数表的指针vptr指向的值,vtable的地址.... 下一页