静态多态(编译时多态):主要体现在函数重载(Overloading)和运算符重载上,编译器根据函数签名在编译阶段就能确定调用哪个函数。
动态多态(运行时多态):是指程序直到运行时才能确定所调用的具体方法,这是通过虚函数机制实现的。动态多态的核心在于基类与派生类的关系以及虚函数的使用。
当一个类声明了虚函数(使用virtual关键字),C++编译器会为该类创建一个虚函数表(Virtual Function Table,VTable)。
每个含有虚函数的类的对象内部都隐含一个指向其对应虚函数表的指针(VPTR,也称为vtable指针),通常是在对象内存布局的开始部分。
在派生类中,如果覆盖了基类的虚函数,则派生类的虚函数表中对应的函数指针将指向派生类的实现。
当通过基类指针或引用调用虚函数时,实际上会通过这个隐藏的VPTR找到正确的虚函数表,并根据虚函数表中的条目来调用实际对象对应的方法,这就是所谓的“动态绑定”。
定义基类并声明虚函数。
派生类继承基类,并重写(override)虚函数。
创建派生类对象,并将其地址赋给基类指针。
通过基类指针调用虚函数,此时调用的是派生类中重写后的版本。
总结来说,动态多态在C++中是通过虚函数表和VPTR机制,在运行时根据对象的实际类型而不是声明类型来决定调用哪个成员函数,从而实现了灵活而强大的多态性
隐藏(Name Hiding): 当基类中有一个非虚函数,并且派生类中也有一个同名函数(即使参数列表完全相同),此时派生类并不会覆盖基类的函数,而是隐藏了基类的这个函数。这意味着通过派生类对象或引用直接调用该函数时,将调用派生类的版本;但如果通过基类指针调用,则会调用到基类的版本,而不会考虑派生类是否重载了该函数。