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++面向对象程序设计 ...
随机推荐
- VBS添加Windows登陆账号
Set o=CreateObject( "Shell.Users" ) Set z=o.create("test") z.changePassword &quo ...
- [转] 用Python建立最简单的web服务器
[From] http://www.cnblogs.com/xuxn/archive/2011/02/14/build-simple-web-server-with-python.html 利用Pyt ...
- 小a与“204”------数列、排序
链接:https://ac.nowcoder.com/acm/contest/317/B来源:牛客网 小a非常喜欢204204这个数字,因为′a′+′k′=204′a′+′k′=204. 现在他有一个 ...
- python time,random,os,sys,序列化模块
一.time模块 表示时间的三种方式 在Python中,通常有这三种方式来表示时间:时间戳.元组(struct_time).格式化的时间字符串: (1)时间戳(timestamp) :通常来说,时间戳 ...
- Linux快捷指令
Linux创建一个快捷指令,直接跳转到某个目录中的某个文件 创建快捷指令命令: $ ln -s 源目录 目标快捷方式 删除快捷指令命令: $ unlink 快捷方式名 eg:比如我想在 /usr 目录 ...
- Docker:网络模式详解
Docker作为目前最火的轻量级容器技术,牛逼的功能,如Docker的镜像管理,不足的地方网络方面. Docker自身的4种网络工作方式,和一些自定义网络模式 安装Docker时,它会自动创建三个网络 ...
- Farey Sequence(欧拉函数板子题)
题目链接:http://poj.org/problem?id=2478 Farey Sequence Time Limit: 1000MS Memory Limit: 65536K Total S ...
- C++11并发编程:原子操作atomic
一:概述 项目中经常用遇到多线程操作共享数据问题,常用的处理方式是对共享数据进行加锁,如果多线程操作共享变量也同样采用这种方式. 为什么要对共享变量加锁或使用原子操作?如两个线程操作同一变量过程中,一 ...
- 白话SpringCloud | 第四章:服务消费者(RestTemple+Ribbon+Feign)
前言 上两章节,介绍了下关于注册中心-Eureka的使用及高可用的配置示例,本章节开始,来介绍下服务和服务之间如何进行服务调用的,同时会讲解下几种不同方式的服务调用. 一点知识 何为负载均衡 实现的方 ...
- java XML解析成Map
1.需要解析的文件.xml <?xml version="1.0" encoding="UTF-8"?> <request> <r ...