为什么基类指针(或引用)可以调用派生类的private虚函数
2017-07-18 14:25
387 查看
在基类中定义了public虚函数,在派生类中将其重写,但是设置为private,为什么通过基类指针仍然可以发生动态绑定调用派生类中的private虚函数?
例子如下:
更进一步的解释:当pBase->Disp()时,首先通过这个对象的vptr找到对应的vtable, 因为它实际上是Derived对象,所以找到的是Derived的虚表,所有的Derived对象都共用这个虚表。又因为是通过基类的指针调用的,编译器从Base的类型信息中查到Disp是虚表中的第一个entry, 而且这个函数的访问权限是public的,所以首先它让你调用,其次,从虚表第一个entry中取出的函数地址对应着Derived::Disp, 所以最后是Derived::Disp被调用,Derived::Disp在Derived中的访问权限在这里是无关的了,编译器根本不会费事去查询这一信息。甚至这一信息可能根本编译器也不知道。
例子如下:
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(); // 显示的结果是派生类的虚函数被调用! }正确的解释:派生类中虚函数的访问权限是在编译阶段由基类确定的,在运行阶段不再检查访问权限,所以,虚函数的访问权限与派生类就没关系了。
更进一步的解释:当pBase->Disp()时,首先通过这个对象的vptr找到对应的vtable, 因为它实际上是Derived对象,所以找到的是Derived的虚表,所有的Derived对象都共用这个虚表。又因为是通过基类的指针调用的,编译器从Base的类型信息中查到Disp是虚表中的第一个entry, 而且这个函数的访问权限是public的,所以首先它让你调用,其次,从虚表第一个entry中取出的函数地址对应着Derived::Disp, 所以最后是Derived::Disp被调用,Derived::Disp在Derived中的访问权限在这里是无关的了,编译器根本不会费事去查询这一信息。甚至这一信息可能根本编译器也不知道。
相关文章推荐
- 为什么基类指针和引用可以指向派生类对象,但是反过来不行?
- 为什么基类指针和引用可以指向派生类对象,但是反过来不行?
- [疑问]C/C++中为什么在类外利用多态基类指向派生类指针可以调用类的私有成员函数?
- 为什么基类指针和引用可以指向派生类对象,但是反过来不行?
- 为什么基类指针和引用可以指向派生类对象,但是反过来不行?
- C/C++中为什么在类外利用多态基类指向派生类指针可以调用类的私有成员函数?
- 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针
- 基类指针为什么可以指向派生类,而派生类指针不可以指向基类
- 解释为什么基类的析构函数不为虚的话,基类指针指向子类对象,删除对象时,派生类的析构函数就不会被调用
- 为什么基类指针可以指向派生类对象,而派生类则不可以指向基类
- 关于C++基类、派生类的引用和指针
- C++中指向派生类的基类指针、基类引用的一点总结
- 非多态的继承情况下,基类指针可以指向派生类对象么?
- 基类指针可以指向派生类对象,派生类指针不可以指向基类对象
- 虚拟函数使得父类指针可以调用派生类的同名函数
- C++中通过派生类调用第二基类的普通成员函数时this指针的调整
- 为什么通过空指针(NULL)可以正确调用类的部分成员函数
- 多态继承情况下,有一个基类指针指向派生类对象,如何用它调用基类的虚函数?
- 为什么C++类定义中,数据成员不能被指定为自身类型,但可以是指向自身类型的指针或引用?
- 【C++】基类指针可以指向派生类对象,派生类指针不可以指向基类对象