简述父类写了一个virtual 函数,如果子类覆盖它的函数不加virtual ,也能实现多态 ?
参考答案:
是的,子类覆盖父类的非virtual
函数也能实现多态,但这种实现方式并不是动态多态(也称为运行时多态),而是静态多态(也称为编译时多态)。
当我们说多态时,我们通常指的是根据对象的实际类型来调用相应的函数版本。这在两种情况下都可以发生:
- 静态多态:这发生在编译时。当我们在代码中明确指定了对象的类型时,编译器会根据该类型来确定应该调用哪个函数。例如,如果我们有一个基类指针指向一个派生类对象,并且该基类的函数没有被声明为
virtual
,则编译器会在编译时确定应该调用哪个版本的函数。 - 动态多态:这发生在运行时。当我们使用
virtual
关键字声明一个函数时,编译器会为该函数生成一个虚函数表(vtable),并在运行时根据对象的实际类型来确定应该调用哪个版本的函数。这种多态允许我们在运行时动态地改变对象的行为。
如果你在父类中声明了一个非virtual
函数,并在子类中覆盖它,那么你将实现静态多态。这意味着编译器将在编译时确定应该调用哪个版本的函数,而不是在运行时。这可能会导致一些意外的行为,因为如果你试图通过基类指针或引用来调用该函数,并且期望实现动态多态,那么实际上你将得到的是基类版本的函数,而不是派生类版本的函数。
因此,为了确保实现动态多态,建议在父类中将要覆盖的函数声明为virtual
。
学习笔记