直接看示例代码
#include
using namespace std;
class Father
{
public:
Father(){};
virtual void func()
{
cout<<"Father"< } void func2() { cout<<"Father_func2"< }; class Child:public Father { public: Child(){}; virtual void func() { cout<<"Child"< } void func2() { cout<<"Child_func2"< }; int main() { Father f; Child c; f=c; f.func2();//只能调用基类中函数,输出“Father_func2” f.func();//通过对象名调用,输出“Father” Father &fa=c; fa.func();//通过引用调用,输出“Child” Father *fat=&c; fat->func();//通过指针调用,输出“Child” return 0; } 可以得出如下结论: 通过子类赋值给父类,然后调用虚函数,不会引发动态绑定。通过子类赋值给父类,然后调用成员函数(无论是否为虚函数),如示例中f.func2()的方式,只能调用派生类中的基类成员,而不能访问派生类增加的成员(同名函数按基类和派生类区分开);通过指针和引用调用虚函数,可以实现运行时多态,具体实现涉及虚函数指针vptr和虚函数表vtbl相关知识。通过对象名调用虚函数,在编译阶段就能确定调用的是哪一个类的虚函数,所以属于静态关联,如果通过基类指针调用虚函数,在编译阶段无法从语句本身确定调用哪一个类的虚函数,只有在运行时,指针指向某一具体对象后,才能确定调用的是哪一个类的虚函数,故为动态关联; tips: 动态联编是指在程序运行的时候,编译器才去判断调用哪个函数或如何执行程序。如if-else结构、switch结构等。静态联编是指程序在编译阶段就确定了如何执行。