重载、重写、隐藏的区别
函数重载
重载是指同一可访问区内被声明几个具有不同参数列(参数的类型、个数、顺序)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。
1 | class A { |
函数隐藏
函数隐藏是指派生类的函数屏蔽了与其同名的基类函数,只要是与基类同名的成员函数,不管参数列表是否相同,基类函数都会被隐藏。
1 |
|
上述代码中 ex.fun(1, 0.1);
出现错误,说明派生类中将基类的同名函数隐藏了。若是想调用基类中的同名函数,可以加上类型名指明 ex.Base::fun(1, 0.1);
,这样就可以调用基类中的同名函数。
函数重写(覆盖)
函数覆盖是指派生类中存在重新定义的函数。函数名、参数列表、返回值类型都必须同基类中被重写的函数一致,只有函数体不同。派生类调用时会调用派生类的重写函数,不会调用被重写函数。基类中被重写的函数必须是虚函数,被 virtual
修饰。
1 |
|
重写和重载的区别
- 范围区别:对于类中函数的重载或者重写而言,重载发生在同一个类的内部,重写发生在不同的类之间(子类和父类之间)。
- 参数区别:重载的函数需要与原函数有相同的函数名、不同的参数列表,不关注函数的返回类型;重写的函数的函数名、参数列表和返回值类型都需要和原函数相同,父类中被重写的函数需要被
virtual
修饰。 - virtual 关键字:重写的函数基类中必须有 virtual 关键字的修饰,重载的函数有没有都行。
隐藏和重载、重写的区别
- 范围区别:隐藏与重载范围不同,隐藏发生在不同类中。
- 参数区别:隐藏函数和被隐藏函数参数列表可以相同,也可以不同,但函数名一定相同;当参数名不同时,无论基类中的函数是否被 virtual 修饰,基类函数都是隐藏,而不是重写。
- 利用重写可以实现多态,而隐藏不可以。如果使用基类指针指向派生类对象,利用这个指针调用函数时,对于隐藏的函数,会根据指针的类型区调用函数;对于重写的函数,会根据指针所指向对象的类型去调用函数。重写必须使用
virtual
关键字,此时会更改派生类虚函数表的表项。 - 隐藏是发生在编译时,在编译时由编译器实现隐藏,而重写一般发生在运行时,即运行时会查找类的虚函数表,决定调用的函数接口。
参考
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 PEACE's Blog!