重载、覆盖和隐藏的区别

分类: C++ 学习笔记 学习心得与方法 2013-09-26 11:21 50人阅读 评论(0) 收藏 举报

“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关键字。

  比如,在下面的程序中:

  1. #include <iostream>
  2. using namespace std;
  3. class A
  4. {
  5. public:
  6. void f(int x){cout<<"A::f(int) "<<x<<endl;}
  7. void f(float x){cout<<"A::f(float) "<< x<<endl;}
  8. virtual void g(void){cout<< "A::g(void)"<<endl;}
  9. };
  10. class B : public A
  11. {
  12. public:
  13. virtual void g(void){cout<<"B::g(void)"<<endl;}
  14. };
  15. int  main(void)
  16. {
  17. B d;
  18. A *p = &d;
  19. p->f(42); // 运行结果:A::f(int) 42
  20. p->f(3.14f); // 运行结果:A::f(float) 3.14
  21. d.g();// 运行结果:B::g(void)
  22. p->g(); // 运行结果:B::g(void)
  23. /*
  24. 运行结果显示:
  25. A::f(int) 42
  26. A::f(float) 3.14
  27. B::g(void)
  28. B::g(void)
  29. 请按任意键继续. . .
  30. */
  31. return 0;
  32. }

  函数A::f(int)与A::f(float)相互重载,而A::g(void)被B::g(void)覆盖。

  隐藏是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
  1) 如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
  2) 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

  比如,在下面的程序中:

  1. #include <iostream>
  2. using namespace std;
  3. class A
  4. {
  5. public:
  6. virtual void f(float x){cout<<"A::f(float) "<<x<<endl;}//虚函数
  7. void g(float x){cout<<"A::g(float) "<<x<<endl;}
  8. void h(float x){cout<<"A::h(float) "<<x<<endl;}
  9. };
  10. class B : public A
  11. {
  12. public:
  13. virtual void f(float x){cout<<"B::f(float) "<<x<<endl;}//虚函数
  14. void g(int x){cout<<"B::g(int) "<<x<<endl;}
  15. void h(float x){cout<<"B::h(float) "<<x<<endl;}
  16. using A::g;//这句话是用来引用父类中被隐藏的部分的。
  17. };
  18. int main(void)
  19. {
  20. B test1;
  21. A *p = &test1;
  22. test1.g(99);//B::g(int) 99
  23. test1.h(88.8);//B::h(float) 88.8
  24. //下面显示了虚函数的功能
  25. test1.f(66.6);//B::f(float) 66.6
  26. p->f(55.5);//B::f(float) 55.5
  27. A test2;
  28. p = &test2;
  29. p->f(33.3);//A::f(float) 33.3
  30. /*
  31. 输出结果是:
  32. B::g(int) 99
  33. B::h(float) 88.8
  34. B::f(float) 66.6
  35. B::f(float) 55.5
  36. A::f(float) 33.3
  37. 请按任意键继续. . .
  38. */
  39. return 0;
  40. }

通过分析可知:
(1. 函数B::g(int)隐藏了A::g(float),注意,不是重载。
(2. 函数B::h(float)隐藏了A::h(float),注意,不是覆盖。
(3. 函数B::f(float)覆盖了A::f(float),有virtual。

  看完前面的示例,可能大家还没明白隐藏与覆盖到底有什么区别,因为我们前面都是讲的表面现象,怎样的实现方式,属于什么情况。下面我们就要分析覆盖与
隐藏在应用中到底有什么不同之处。在下面的程序中bp和dp指向同一地址,按理说运行结果应该是相同的,可事实并非如此。

  1. <pre class="cpp" name="code">int main(void)
  2. {
  3. B b;
  4. A *p_a = &b;
  5. B *p_b = &b;
  6. //good:behavior依赖于对象的类型
  7. p_a->f(3.14f);
  8. p_b->f(3.14f);
  9. //bad:bahavior依赖于指针类型
  10. p_a->g(3.14f);
  11. p_b->g(3.14f);
  12. //bad:behavior依赖于指针类型
  13. p_a->h(3.14f);
  14. p_b->h(3.14f);
  15. /*
  16. B::f(float) 3.14
  17. B::f(float) 3.14
  18. A::g(float) 3.14
  19. B::g(int) 3
  20. A::h(float) 3.14
  21. B::h(float) 3.14
  22. 请按任意键继续. . .
  23. */
  24. return 0;
  25. }</pre><br>

原文出自【比特网】,转载请保留原文链接:http://soft.chinabyte.com/database/348/12279348.shtml

ZT C++ 重载、覆盖和隐藏的区别的更多相关文章

  1. java的重载、覆盖和隐藏的区别

    重载:方法名相同,但参数不同的多个同名函数 注意:1.参数不同的意思是参数类型.参数个数.参数顺序至少有一个不同 2.返回值和异常以及访问修饰符,不能作为重载的条件(因为对于匿名调用,会出现歧义,eg ...

  2. C++中重载、覆盖和隐藏的区别,以及适用场景

    一.重载.覆盖和隐藏的区别 二.适用场景 1.重载: 适用于不同的数据类型都需要使用到的功能函数.以数据相加的函数为例,可以在同一个文件内提供以下的重载函数以支持同样的功能: int add(int, ...

  3. Java_类和对象(完美总结)_转载_覆盖和隐藏的区别,覆盖就不能使用了,而隐藏提供全局方法名或者全局变量名还可以使用

    转载自海子:http://www.cnblogs.com/dolphin0520/p/3803432.html Java:类与继承 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封 ...

  4. C++中重载、覆盖与隐藏的区别(转)

    本文摘自林锐博士的<高质量C++/C编程指南>. 成员函数的重载.覆盖(override)与隐藏很容易混淆,C++程序员必须要搞清楚概念,否则错误将防不胜防. 1.重载与覆盖 成员函数被重 ...

  5. C++之重载覆盖和隐藏

    继承体系下同名成员函数的三种关系 重载 在同一作用域内 函数名相同,参数列表不同(分三种情况:参数个数不同,参数类型不同,参数个数和类型都不同) 返回值类型可以相同也可以不同 重写(覆盖) 在不同作用 ...

  6. C++类成员函数的重载、覆盖和隐藏区别?

    C++类成员函数的重载.覆盖和隐藏区别? a.成员函数被重载的特征:(1)相同的范围(在同一个类中):(2)函数名字相同:(3)参数不同:(4)virtual 关键字可有可无.b.覆盖是指派生类函数覆 ...

  7. 【转】c++重载、覆盖、隐藏——理不清的区别

    原文网址:http://blog.sina.com.cn/s/blog_492d601f0100jqqm.html 再次把林锐博士的<高质量c++编程指南>翻出来看的时候,再一次的觉得这是 ...

  8. C++:类成员函数的重载、覆盖和隐藏区别?

    #include <iostream> class A { public: void func() { std::cout << "Hello" <& ...

  9. C++中重载、重写(覆盖)和隐藏的区别实例分析

    这篇文章主要介绍了C++中重载.重写(覆盖)和隐藏的区别,是C++面向对象程序设计非常重要的概念,需要的朋友可以参考下 本文实例讲述了C++中重载.重写(覆盖)和隐藏的区别,对于C++面向对象程序设计 ...

随机推荐

  1. c++ 编程调试秘笈

    美.Vladimir Kushnir . O'REILLY. 人邮 .2013.1 c++大部分缺陷来源于c MyClass* object = new MyClass(); delete objec ...

  2. 1149 Dangerous Goods Packaging (25 分)

    When shipping goods with containers, we have to be careful not to pack some incompatible goods into ...

  3. 破解mysql数据库的密码

    发现的1小问题 语句打错以后应该退出本语句,再继续打新语句.也可以打\c,退出本语句. 如何破解数据库的密码: 1:通过任务管理器或者服务管理,关掉mysqld(服务进程) 2:通过命令行+特殊参数开 ...

  4. PHP_$_SERVER中QUERY_STRING,REQUEST_URI的用法

    $_SERVER存储当前服务器信息,其中有几个值如 $_SERVER["QUERY_STRING"], $_SERVER["REQUEST_URI"], $_S ...

  5. Linux mmap 要主动释放共享内存

    #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/sta ...

  6. kafaka安装

    wget https://mirrors.cnnic.cn/apache/kafka/2.0.0/kafka_2.11-2.0.0.tgz 解压 Tar -xvf kafka_2.11-2.0.0.t ...

  7. 实现类似tail -f file功能

    python版本py3 tail -f file是打印最后10行,然后跟踪文件追加的内容打印出来. python3 以为本方式打开的话,不能回退(f.seek(-1,1)),所有以'rb'方式打开文件 ...

  8. SQLAlchemy安装和使用

    1.SQLAlchemy安装 SQLAlchemy依赖mysql-python驱动,mysql-python目前只有支持py2的版本和mysql5.5的版本 点我:mysql-python链接 版本: ...

  9. 《springcloud 四》服务保护机制

    服务保护机制SpringCloud Hystrix 微服务高可用技术 大型复杂的分布式系统中,高可用相关的技术架构非常重要. 高可用架构非常重要的一个环节,就是如何将分布式系统中的各个服务打造成高可用 ...

  10. 【Linux相识相知】任务计划和周期性任务

    在我们的生活中,有的工作是例行的,例如每年一次加薪.每年给女朋友过一次生日.每天上班都要打卡等,有的工作是临时发生的,例如明天朋友要来访,你需要准备午餐等等. 像很多例行的工作,你一旦忙起来就很容易忘 ...