基类public虚函数在派生类被重写替private仍然可以调用

基类public虚函数在派生类被重写为private仍然可以调用!
在基类中定义了public虚函数,在派生类中将其重写,但是设置为private,为什么通过基类指针仍然可以发生动态绑定调用派生类中的private虚函数?
class Base
{
public:
// public虚函数
virtual void Disp() { cout << "base.\n"; }
};

class Derived : public Base
{
private:
// 重写基类虚函数,但是放在private中
virtual void Disp() { cout << "derived.\n"; }
};

void main()
{
Derived Dobj;
Base *pBase = &Dobj;
pBase->Disp(); // 显示的结果是派生类的虚函数被调用!
}


通过基类指针仍然正确的调用了虚函数。
这里,我的理解是:对于虚函数的动态调用,是与派生类的访问权限无关,其权限是由基类决定的。
因为C++编译器调用函数时,是
1)从静态类型(变量定义的类型)开始查找函数名,
2)找到了函数名之后,检查类型是否匹配(形参和返回值),
3)如果正确则该函数调用的合法,进而编译器生成代码调用函数。如果这个函数是虚函数且通过指针或引用调用,则根据其实际类型确定运行哪个函数版本,否则直接调用函数。
不知道这样理解是否正确,但不管怎么样,还是运行了派生类的private虚函数,感觉很诧异,希望大神们指点一二。

------解决方案--------------------
虚函数是通过虚表来实现的。虚表可以理解为一个函数指针数组,编译器会根据函数名称和原型找到对应函数在虚表中的index. 派生类可能override了基类的实现,这样只是虚表中的函数指针变了,索引并没变。又因为是通过基类的指针调用的,访问权限也是按照基类的。很简单的东西,要解释清楚却很费事 :)
------解决方案--------------------
冲突来自于访问权限是在编译时刻确定的,而动态绑定在运行时确定
------解决方案--------------------
你的情形,当你pBase->Disp()时,首先通过这个对象的vptr找到对应的vtable, 因为它实际上是Derived对象,所以找到的是Derived的虚表,进程正所有的Derived对象都共用这个虚表。然后编译器从Base的类型信息中查到Disp是虚表中的第一个entry, 而且这个函数的访问权限是public的,所以首先它让你调用,其次,从虚表第一个entry中取出的函数地址对应着Derived::Disp, 所以最后是Derived::Disp被调用,Derived::Disp在Derived中的访问权限在这里是无关的了,编译器根本不会费事去查询这一信息。甚至这一信息可能根本编译器也不知道。
------解决方案--------------------
这个问题与多态实现机制无关,试图从虚表角度去解析的行为不过是自我形成的错觉。

真正也是唯一的原因是:可访问性是静态解析的,不是动态解析的。即是说,无论最终覆盖者的可访问性如何,可访问性均取决于函数调用后缀表达式的可访问性。
------解决方案--------------------
参见这个帖子:
http://bbs.****.net/topics/210042197