virtual关键字:将子类与父类的同名函数联系起来,若无该关键字,则子类与父类的同名函数无关系。
初始类的函数为virtual,所有子类的该函数都为virtual
当对某个对象进行upcasting时,如果该对象中的函数为virtual,那么将会调用该对象实际所属类的函数(子类的函数)而非父类的原始函数(运行时才能确定)
底层实现:
有virtual类的对象在头部会生成一个指针vptr,指向一张表vtable,vtable中含有所有的virtual函数的地址,该表中存储的地址不是对象的,而是类的,也就是说同一个类的所有对象的内存中第一个地址的内容是相同的,都是该指针。
赋值过程中,指针vptr是不传递的!!!!
静态绑定:不涉及virtual
动态绑定:涉及virtual,但是通过指针和引用调用函数才会涉及 !!!!!!
其他oop语言都是默认动态绑定,只有c++默认静态绑定(为了效率)
父类和子类同名的virtual函数构成override关系(覆盖/改写)
想要调用父类的virtual函数:Base::func();
基类A中的virtual函数的返回类型可以是A、A的引用、A类型的指针;
A的任意一个子类B的返回类型可以使B的引用、B类型的指针,但是不可以是B!!!
如果在基类A中含有overloadng的函数(同名但返回类型、参数数量/类型不同的函数),子类B中必须override所有的virtual函数(其他语言中默认overloading,不存在namehiding),否则会发生namehiding(父类中所有与子类中的函数同名的函数将被隐藏,无法调用到)