重写虚函数和隐藏非虚函数之间有什么区别?
函数隐藏是一种名称隐藏的形式。它发生在派生类中定义了与基类中的函数同名的函数时。函数隐藏也适用于基类中的名称查找。函数隐藏可以通过改变函数调用的静态类型来解决。
函数重写是与虚函数的概念相关的。当在基类和派生类中声明了具有相同名称、参数类型列表、cv限定符和引用限定符的虚成员函数时,派生类的函数会重写基类的虚函数。调用虚函数时,会使用函数调用表达式的动态类型来确定最终的重写函数。
函数隐藏和函数重写的不同之处在于,无论派生类中的函数是否重写了基类的虚函数,基类中的函数总是被同名函数隐藏。查找函数名称时,使用表达式的静态类型。函数隐藏只影响到与隐藏的函数具有相同名称的所有重载函数。
在函数重写中,只有具有相同参数的基类函数才会被重写,但可以对虚函数进行重载。
当基类的非虚方法调用基类中的虚方法时,从派生类调用该非虚方法将触发派生类中的重写方法,而不是原始的基类虚方法。
覆盖虚函数和隐藏非虚函数之间的区别在于,根据定义,在前一种情况下,目标函数是根据调用中使用的对象表达式的动态类型选择的,而在后一种情况下,使用的是静态类型。
这就是所有的区别。通过p2->doA()
和p2->doB()
的调用,您的示例清楚地说明了这种区别。表达式*p2
的静态类型是Parent
,而同一表达式的动态类型是Child
。这就是为什么p2->doA()
调用Parent::doA
,而p2->doB()
调用Child::doB
。
在涉及到这种区别的上下文中,名称隐藏根本就没有涉及。
谢谢,静态动态的部分正是我在寻找的内容;很有道理。因此,无论何时可以使用,函数隐藏在速度方面都更好,但如果正在使用基类类型,通常情况下不会出现这种情况。
第一段总结了任何可能的答案和100个例子。谢谢!
虚函数重写和非虚函数隐藏之间的区别是什么?这个问题的出现是因为在C++中,存在着函数的重写和隐藏两种不同的机制。当一个派生类继承了一个基类时,如果基类的成员函数被派生类重新定义并且在基类中被声明为虚函数,那么这个成员函数就是被重写的。而当一个派生类定义了一个与基类中的同名函数,但没有在基类中声明为虚函数时,这个成员函数就是被隐藏的。
解决方法是在派生类中可以使用作用域解析运算符来调用基类中被隐藏的成员函数。例如,可以使用Parent::doA()
来调用基类Parent
的doA()
函数。另外,可以通过将指向派生类对象的基类指针进行类型转换为派生类指针,然后调用派生类中的函数来解决这个问题。
这个问题的输出结果是:
doA in Parent doA in Parent doA in Child doB in Parent doB in Child doB in Child
总之,无论成员函数是否被声明为虚函数,都可以在派生类中使用名称解析来调用基类的成员函数。同时,通过使用作用域解析运算符和进行类型转换,可以解决派生类隐藏基类函数的问题。