在 C++ 的OO模型中,很重要的一个特性是运行时多态。运行时多态是通过类的虚方法实现的。看下面这个例子:
struct IObject {
  virtual void MethodA() = 0;  
  virtual int  MethodB(char *) = 0;
};
class A : public IObject {
public:
  virtual void MethodA() {
    std::cout << "method A" << std::endl;
  };
  virtual int MethodB(char *p) {
    std::cout << "method B " << p << std::endl;
    return 0;
  };
public:
  int MethodC(int c) {
    std::cout << "method C non-virtual" << std::endl;
    return ++c;
  }
private:
  int mem_;
};
int main(int argc, cahr *argv[]) 
{
  IObject *pObj = new A;
  pObj->MethodA();
  pObj->MethodB(NULL);
  // FIXME: This is a compile error!
  pObj->MethodC(1); // error
  delete A;
  return 0;
};
C++ 运行时多态, 在执行代码中,主要通过 vtable 实现。让我们用C来重新描述上面的例子。
// VTABLE of class IObject
struct I_IObject {
  void *pMethodA(void);
  int  *pMethodB(char *);
};
// Instance variant type of IObject
struct IObject {
  struct I_IObject *vtable_this;
};
// VTABLE of class A
struct A;
struct I_A {
  void *pDtor(A*) 
};
// Instance object variant type of class A
struct A {
  struct I_IObject *vtable_IObject;
  struct I_A *vtable_this;
  int *pMethodC(int);
  int mem_;
};
void A_MethodA (void) {
  printf("method A\n"); 
}
int  A_MethodB (char *p) {
  printf("method B %s\n", p);
}
int  A_MethodC (int c) {
  printf("method C non-virtual\n");
  return ++c;
}
void A_dtor(struct A *_this) {
  free(_this);
}
struct A *A_ctor() {
  struct A *p = malloc(sizeof(struct A));
  // Non-virtual function will be assign the value directly.
  p.pMethodC = &A_MethodC;
  /////////////////////////////////////////////////
  // vtable initialization code
#ifdef A_MethodA
  p.vtable_IObject->pMethodA = &A_MethodA;
#else
  p.vtable_IObject->pMethodA = &IObject_MethodA; // Warning!
#endif
#ifdef A_MethodB
  p.vtable_IObject->pMethodB = &A_MethodB;
#else
  p.vtable_IObject->pMethodB = &IObject_MethodB; // Warning!
#endif
  // vtable of A itself
  p.vtable_self->pDtor = &A_dtor;
  return p;
}
int main(int argc, char *argv[]) 
{
  IObject *pObj = (IObject*) A_ctor();
  pObj->vtable_self->pMethodA();
  pObj->vtable_self->pMethodB(NULL);
  A_dtor(pObj);
  return 0;
}
C的定价物确实有些繁琐,不过基本的结构就是这样了。具体说来是这样:
1,如果一个类 virtual function, 这些 virtual funciton 就会被统一在一个 vtable 中;
2,包含 virtual function 的class 都会有一个指向 vtable structure的指针,如果当前类重写了 virtual function, 在对象初始化的时候相应的虚函数指针就会被替换;
3,虚函数的调用一律通过vtable定位,因为存在vtable这一层中继,就可以保证在运行态可以通过父类的指针执行指向子类对象的方法,因为类对象初始化的时候正确的重写了vtable的内容。 
4,一个对象多一个包含virtual function的基类,就会在类变量的结构中多引入一个指向父类vtable structure的指针。在类对象初始化的时候,就需要更多的 vtable 初始化代码。:D
多重继承会导致 vtable 膨胀, Microsoft ATL 引入了一个 ATL_NO_VTABLE __declspec(novtable) C++ 扩展。关于这个,下回再说~~~
其实这个例子里面还有一个小问题, 不知道大家能不能看出来啊!