单一继承下基类private虚函数在派生类中能否访问??
在用户程序中,派生类对象的虚指针指向的虚函数表中是仍然有基类private虚函数的条目,但是由于属性为private,无法实现正常的访问!//
通过得到private虚函数的地址强制访问说明其确实存在于子类的虚函数表中!
事实上,多态性与将实现多态的函数的访问限定符没有任何关系,private 函数仍然可以实现多态,它的指针仍然位于vtbl中;
只不过该函数的多态一般只能在基类的内部由其他非虚函数调用该函数的时候反映出来,
访问限定符仅仅限制外部对类的成员的访问权限,它并没有破坏以下规则:
通过基类指针或引用调用成员函数时,如果该函数时非虚的,那么将采用静态绑定,即编译时绑定;如果该函数是虚拟的,则采用动态绑定,即运行时绑定。二、virtual与访问限定符结合
派生类只有一个虚函数表,派生类对象只有一个虚指针来指向这个虚函数表。
虚函数表中按照基类虚函数(若派生类override基类的虚函数,则虚函数表中原先存放的基类虚函数的地址变为相应的派生的虚函数的地址)、派生类新增的虚函数顺序依次排列。
class Base
{
public:
int x;
virtual void f(){cout << "Base::f" << endl;}
virtual void g(){cout << "Base::g" << endl;}
private:
virtual void h(){cout << "Base::h" << endl;}
};
class Derive:public Base
{
public:
int y;
virtual void f(){cout << "Derive::ff" << endl;}
virtual void g(){cout << "Derive::gg" << endl;}
virtual void hh(){cout << "Derive::hh" << endl;}
};
typedef void (*Fun)();
int main()
{
Fun pFun;
Base *b = new Base;
//b->h(); //出错,不具有访问属性!
Derive derive;
Derive *de = &derive;
de->f(); //通过virtual机制实现动态绑定
de->Base::f(); //可以显示调用基类的f()仅仅是因为f()属性是public,用户函数可以调用;这与虚机制无关
//基类中声明为private的虚函数,派生类指针通过virtual函数调用和显示调用都不可以访问!! 没有提供访问属性!
//de->h(); //出错
//de->Base::h(); //由于h()为基类private,不可访问!!
Base *be = &derive;
be->f();
be->g();
//be->h(); //出错!因为be实际上是指向derive对象的指针!不可访问
//通过获取private虚函数指针,如下((Fun)((*q)[3]))实现访问!
void*** q = (void***)&derive;
pFun = (Fun)(**q);
pFun();
pFun = (Fun)((*q)[1]);
pFun();
pFun = (Fun)((*q)[2]);
pFun();
pFun = (Fun)((*q)[3]); //pFun为指向Base::h()的指针
pFun(); //通过获得实际指针,可以实现基类private虚函数的访问!!这也说明即使将基类的虚函数声明为private,派生类的vftp所指向的虚函数表中确实是仍然存在该虚函数的!只是像上面那样直接使用对象指针de实现调用是不能完成的!
pFun = (Fun)((*q)[4]);
system("pause");
return 0;
}