重载(overload)、覆盖(override)、隐藏(hide)的区别 (转)
转自http://blog.csdn.net/yanjun_1982/archive/2005/09/02/470405.aspx
这三个概念都是与OO中的多态有关系的。如果单是区别重载与覆盖这两个概念是比较容易的,但是隐藏这一概念却使问题变得有点复杂了,下面说说它们的区别吧。
重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。
覆盖(也叫重写)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。
隐藏是指派生类中的函数把基类中相同名字的函数屏蔽掉了。
如果派生类函数与基类函数同名,但参数不同,无论基类函数前是否有virtual修饰,基类函数被隐.
如果派生类函数与基类函数同名,参数也相同,但是基类函数前无virtual修饰,基类函数被隐藏。
#include <iostream.h> class Base { public: virtual void f(float x){ cout << "Base::f(float) " << x << endl; } void g(float x){ cout << "Base::g(float) " << x << endl; } void h(float x){ cout << "Base::h(float) " << x << endl; } }; class Derived : public Base { public: virtual void f(float x){ cout << "Derived::f(float) " << x << endl; } void g(int x){ cout << "Derived::g(int) " << x << endl; } void h(float x){ cout << "Derived::h(float) " << x << endl; } };
看出什么了吗?下面说明一下:
(1)函数Derived::f(float)覆盖了Base::f(float)。
(2)函数Derived::g(int)隐藏了Base::g(float),而不是重载。
(3)函数Derived::h(float)隐藏了Base::h(float),而不是覆盖。
void main(void) { Derived d; Base *pb = &d; Derived *pd = &d; // Good : behavior depends solely on type of the object pb->f(3.14f); // Derived::f(float) 3.14 pd->f(3.14f); // Derived::f(float) 3.14 // Bad : behavior depends on type of the pointer pb->g(3.14f); // Base::g(float) 3.14 pd->g(3.14f); // Derived::g(int) 3 (surprise!) // Bad : behavior depends on type of the pointer pb->h(3.14f); // Base::h(float) 3.14 (surprise!) pd->h(3.14f); // Derived::h(float) 3.14 }
在第一种调用中,函数的行为取决于指针所指向的对象。在第二第三种调用中,函数的行为取决于指针的类型。所以说,隐藏破坏了面向对象编程中多态这一特性,会使得OOP人员产生混乱。
如果pd想要调用Base::g(float),可以用pd->Base::g(3.14f),增加基类作用域的形式来实现。
当基类定于多个同名函数的时候,只要派生类中出现了一个或多个相应的同名函数,这个时候会隐藏基类所有的相应同名函数
#include <iostream> using namespace std; class Base { public: void Fun() { cout << "Func" << endl; } void Fun(int c ) { cout << "Fun" << c << endl; } }; class Dervied : public Base { public: void Fun() { cout << "Func Dervied" << endl; } }; int main() { Dervied d; d.Fun(); d.Fun(2); return 0; } error: no matching function for call to 'Dervied::Fun(int)' note: candidates are: void Dervied::Fun()
从上面的列子可以看出,虽然派生类中只定义了一个 与基类同名的函数,但是它隐藏了基类所有的同名函数。所以从中可以看出,隐藏和名称相关和其他没有关系,只要派生类中定义了同名函数,那在基类中所有的同名函数都会被隐藏,与参数和个数无关。
当覆盖(重写)遇到隐藏
当我们覆盖(重写)基类的虚函数的时候也会发生隐藏,就像下面的列子我们从基类继承了俩个函数,我们只重写了一个函数,但是剩下没有被重写的基类函数我们也无法使用了,它被隐藏了起来
#include <iostream> using namespace std; class Base { public: virtual void Fun() { cout << "Func" << endl; } void Fun(int c ) { cout << "Fun" << c << endl; } }; class Dervied : public Base { public: void Fun(char c) { cout << "Func Dervied" << endl; } }; int main() { Dervied d; d.Fun(); d.Fun(2); return 0; } In function 'int main()': error: no matching function for call to 'Dervied::Fun()' note: candidates are: void Dervied::Fun(char)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2016-03-25 android中Camera setDisplayOrientation使用