ZT C++ 重载、覆盖和隐藏的区别
重载、覆盖和隐藏的区别
“overload”翻译过来就是:超载,过载,重载,超出标准负荷;“override”翻译过来是:重置,覆盖,使原来的失去效果。
先来说说重载(Overload)的含义,在日常生活中我们经常要清洗一些东西,比如洗车、洗衣服。尽管我们说话的时候并没有明确地说用洗车的 方式来洗车,或者用洗衣服 的方式来洗一件衣服,但是谁也不会用洗衣服的方式来洗一辆车,否则等洗完时车早就散架了。我们并不要那么明确地指出来就心知肚明,这就有重载的意思了。在 同一可访问区内被声名的几个具有不同参数列的(参数的类型、个数、顺序不同)同名函数,程序会根据不同的参数列来确定具体调用哪个函数,这种机制叫重载, 重载不关心函数的返回值类型。这里,“重载”的“重”的意思不同于“轻重”的“重”,它是“重复”、“重叠”的意思。例如在同一可访问区内有:
① double calculate(double);
② double calculate(double,double);
③ double calculate(double, int);
④ double calculate(int, double);
⑤ double calculate(int);
⑥ float calculate(float);
⑦ float calculate(double);
六个同名函数calculate,①②③④⑤⑥中任两个均构成重载,⑥和⑦也能构成重载,而①和⑦却不能构成重载,因为①和⑦的参数相同。
函数重载:两个函数的形式参数必须不同(比如参数类型、参数个数和参数顺序,这三者中必须至少有一个不同),而函数的返回值类型可以相同也可以不相同,也就是说函数的返回值类型与函数是否发生重载是没有关系的。
覆盖(Override)是指派生类中存在重新定义的函数,其函数名、参数列、返回值类型必须同父类中的相对应被覆盖的函数严格一
致,覆盖函数和被覆盖函数只有函数体
(花括号中的部分)不同,当派生类对象调用子类中该同名函数时会自动调用子类中的覆盖版本,而不是父类中的被覆盖函数版本,这种机制就叫做覆盖。
下面我们从成员函数的角度来讲述重载和覆盖的区别。
成员函数被重载的特征有:
1) 相同的范围(在同一个类中);
2) 函数名字相同;
3) 参数不同;
4) virtual关键字可有可无。
覆盖的特征有:
1) 不同的范围(分别位于派生类与基类);
2) 函数名字相同;
3) 参数相同;
4) 基类函数必须有virtual关键字。
比如,在下面的程序中:
- #include <iostream>
- using namespace std;
- class A
- {
- public:
- void f(int x){cout<<"A::f(int) "<<x<<endl;}
- void f(float x){cout<<"A::f(float) "<< x<<endl;}
- virtual void g(void){cout<< "A::g(void)"<<endl;}
- };
- class B : public A
- {
- public:
- virtual void g(void){cout<<"B::g(void)"<<endl;}
- };
- int main(void)
- {
- B d;
- A *p = &d;
- p->f(42); // 运行结果:A::f(int) 42
- p->f(3.14f); // 运行结果:A::f(float) 3.14
- d.g();// 运行结果:B::g(void)
- p->g(); // 运行结果:B::g(void)
- /*
- 运行结果显示:
- A::f(int) 42
- A::f(float) 3.14
- B::g(void)
- B::g(void)
- 请按任意键继续. . .
- */
- return 0;
- }
函数A::f(int)与A::f(float)相互重载,而A::g(void)被B::g(void)覆盖。
隐藏是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
1) 如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
2) 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
比如,在下面的程序中:
- #include <iostream>
- using namespace std;
- class A
- {
- public:
- virtual void f(float x){cout<<"A::f(float) "<<x<<endl;}//虚函数
- void g(float x){cout<<"A::g(float) "<<x<<endl;}
- void h(float x){cout<<"A::h(float) "<<x<<endl;}
- };
- class B : public A
- {
- public:
- virtual void f(float x){cout<<"B::f(float) "<<x<<endl;}//虚函数
- void g(int x){cout<<"B::g(int) "<<x<<endl;}
- void h(float x){cout<<"B::h(float) "<<x<<endl;}
- using A::g;//这句话是用来引用父类中被隐藏的部分的。
- };
- int main(void)
- {
- B test1;
- A *p = &test1;
- test1.g(99);//B::g(int) 99
- test1.h(88.8);//B::h(float) 88.8
- //下面显示了虚函数的功能
- test1.f(66.6);//B::f(float) 66.6
- p->f(55.5);//B::f(float) 55.5
- A test2;
- p = &test2;
- p->f(33.3);//A::f(float) 33.3
- /*
- 输出结果是:
- B::g(int) 99
- B::h(float) 88.8
- B::f(float) 66.6
- B::f(float) 55.5
- A::f(float) 33.3
- 请按任意键继续. . .
- */
- return 0;
- }
通过分析可知:
(1. 函数B::g(int)隐藏了A::g(float),注意,不是重载。
(2. 函数B::h(float)隐藏了A::h(float),注意,不是覆盖。
(3. 函数B::f(float)覆盖了A::f(float),有virtual。
看完前面的示例,可能大家还没明白隐藏与覆盖到底有什么区别,因为我们前面都是讲的表面现象,怎样的实现方式,属于什么情况。下面我们就要分析覆盖与
隐藏在应用中到底有什么不同之处。在下面的程序中bp和dp指向同一地址,按理说运行结果应该是相同的,可事实并非如此。
- <pre class="cpp" name="code">int main(void)
- {
- B b;
- A *p_a = &b;
- B *p_b = &b;
- //good:behavior依赖于对象的类型
- p_a->f(3.14f);
- p_b->f(3.14f);
- //bad:bahavior依赖于指针类型
- p_a->g(3.14f);
- p_b->g(3.14f);
- //bad:behavior依赖于指针类型
- p_a->h(3.14f);
- p_b->h(3.14f);
- /*
- B::f(float) 3.14
- B::f(float) 3.14
- A::g(float) 3.14
- B::g(int) 3
- A::h(float) 3.14
- B::h(float) 3.14
- 请按任意键继续. . .
- */
- return 0;
- }</pre><br>
原文出自【比特网】,转载请保留原文链接:http://soft.chinabyte.com/database/348/12279348.shtml
ZT C++ 重载、覆盖和隐藏的区别的更多相关文章
- java的重载、覆盖和隐藏的区别
重载:方法名相同,但参数不同的多个同名函数 注意:1.参数不同的意思是参数类型.参数个数.参数顺序至少有一个不同 2.返回值和异常以及访问修饰符,不能作为重载的条件(因为对于匿名调用,会出现歧义,eg ...
- C++中重载、覆盖和隐藏的区别,以及适用场景
一.重载.覆盖和隐藏的区别 二.适用场景 1.重载: 适用于不同的数据类型都需要使用到的功能函数.以数据相加的函数为例,可以在同一个文件内提供以下的重载函数以支持同样的功能: int add(int, ...
- Java_类和对象(完美总结)_转载_覆盖和隐藏的区别,覆盖就不能使用了,而隐藏提供全局方法名或者全局变量名还可以使用
转载自海子:http://www.cnblogs.com/dolphin0520/p/3803432.html Java:类与继承 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封 ...
- C++中重载、覆盖与隐藏的区别(转)
本文摘自林锐博士的<高质量C++/C编程指南>. 成员函数的重载.覆盖(override)与隐藏很容易混淆,C++程序员必须要搞清楚概念,否则错误将防不胜防. 1.重载与覆盖 成员函数被重 ...
- C++之重载覆盖和隐藏
继承体系下同名成员函数的三种关系 重载 在同一作用域内 函数名相同,参数列表不同(分三种情况:参数个数不同,参数类型不同,参数个数和类型都不同) 返回值类型可以相同也可以不同 重写(覆盖) 在不同作用 ...
- C++类成员函数的重载、覆盖和隐藏区别?
C++类成员函数的重载.覆盖和隐藏区别? a.成员函数被重载的特征:(1)相同的范围(在同一个类中):(2)函数名字相同:(3)参数不同:(4)virtual 关键字可有可无.b.覆盖是指派生类函数覆 ...
- 【转】c++重载、覆盖、隐藏——理不清的区别
原文网址:http://blog.sina.com.cn/s/blog_492d601f0100jqqm.html 再次把林锐博士的<高质量c++编程指南>翻出来看的时候,再一次的觉得这是 ...
- C++:类成员函数的重载、覆盖和隐藏区别?
#include <iostream> class A { public: void func() { std::cout << "Hello" <& ...
- C++中重载、重写(覆盖)和隐藏的区别实例分析
这篇文章主要介绍了C++中重载.重写(覆盖)和隐藏的区别,是C++面向对象程序设计非常重要的概念,需要的朋友可以参考下 本文实例讲述了C++中重载.重写(覆盖)和隐藏的区别,对于C++面向对象程序设计 ...
随机推荐
- HDU - 6183 动态开点线段树 || 令人绝望的线段树
一看C才[0,50],肯定要开51棵线段树维护y区间的最小x值啦 是男人就上51棵..等等空间爆几倍了 动态开点!51棵线段树用全局节点变量控制,有点像主席树 清空工作很简单,把51个树根清掉然后回收 ...
- HDU - 5067 / HDU - 5418 TSP
集合表示多用[0,n)表示方法 HDU - 5067 经典TSP,每个顶点恰经过一次最优 #include<bits/stdc++.h> #define rep(i,j,k) for(in ...
- hdu 1231 最大连续和
题意:给定一组数,求最大的连续和,且输出开始与结尾 #include<iostream> #include<cstdio> using namespace std; int s ...
- 获取Java class或者jar文件的本地路径
对于常规java class打成jar文件后,要获取它的本地路径,可以用如下方法. final File f = new File(TestClass.class.getProtectionDomai ...
- BeautifulSoup库应用实例
获取博客园本人的积分排名数据: 1. 抓包获取积分排名数据返回接口:http://www.cnblogs.com/belle-ls/mvc/blog/sidecolumn.aspx?blogApp=b ...
- 第四次 Scrum Meeting
第四次 Scrum Meeting 写在前面 会议时间 会议时长 会议地点 2019/4/8 22:00 30min 大运村1号楼3F 附Github仓库:WEDO 例会照片 工作情况总结(4.8) ...
- html中的flv视频播放器
项目中要播放flv视屏,第一时间想到html5的<video>标签,只是很可惜<video>兼容性差也就算了,居然还对格式有明确限制,也就是说只支持Ogg.MPEG4.WebM ...
- 用poi替换ppt中的文字和图片
try { // 获取PPT文件 String pptModelPath =ConfigReadUtil.getInstance().getConfigI ...
- 智能手表ticwatch穿戴体验
前言 可穿戴设备近几年越来越火,最开始是谷歌眼睛.手环,再到手表.VR眼镜,相信未来几年这片领域依旧火热~ 自从谷歌发布Android Wear.苹果发布Apple Watch之后,智能手表的战役就正 ...
- Proguard breaking audio file in assets or raw
http://stackoverflow.com/questions/21440572/proguard-breaking-audio-file-in-assets-or-raw Issue: I h ...