覆盖(override)和重载(overload)的区别

2024-04-12 22:08

本文主要是介绍覆盖(override)和重载(overload)的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!





一. 重载(overload)

1. 重载指的是函数具有的不同的参数列表,而函数名相同的函数。重载要求参数列表必须不同,比如参数的类型不同、参数的个数不同、参数的顺序不同。

2. 如果仅仅是函数的返回值不同是没办法重载的,因为重载要求参数列表必须不同。

3. 程序是根据参数列表来确定具体要调用哪个函数的

4. 看下面几个例子

void Fun(int a);

void Fun(double a);

void Fun(int a, int b);

void Fun(double a, int b);

上面四个函数都可以构成函数重载

int Fun(int a)

void Fun(int a)

//上面两个是无法构成函数重载的,参数列表必须不同


二. 覆盖(重写override)

1. 覆盖是存在类中,子类重写从基类继承过来的函数。但是函数名、返回值、参数列表都必须和基类相同。

2. 当子类的对象调用成员函数的时候,如果成员函数有被覆盖则调用子类中覆盖的版本,否则调用从基类继承过来的函数

3. 如果子类覆盖的是基类的虚函数,可以用来实现多态。

    当子类重新定义基类的虚函数之后,基类指针可以根据赋给它不同子类指针动态的调用子类中的虚函数,可以做到动态绑定,这就是多态。

4. 子类覆盖基类函数的特征

(1)函数名相同、参数相同、返回值相同

(2)如果基类函数是虚函数,子类覆盖虚函数可以实现多态


三. 重载和覆盖的区别

1.重载要求函数名相同,但是参数列表必须不同,返回值可以相同也可以不同

   覆盖要求函数名、参数列表、返回值必须相同


2.在类中重载是同一个类中不同成员函数之间的关系

   在类中覆盖则是子类和基类之间不同成员函数之间的关系


3. 重载函数的调用是根据参数列表来决定调用哪一个函数

    覆盖函数的调用是根据对象类型的不同决定调用哪一个


4. 在类中对成员函数重载是不能够实现多态

    在子类中对基类虚函数的覆盖可以实现多态


看下面这个例子

class Base
{
public:void Fun(int x){cout<<"Base::Fun(int x)"<<endl;}void Fun(double x){cout<<"Base::Fun(double x)"<<endl;}virtual void G(void){cout<<"Base::G(void)"<<endl;}
};class SubClass:public Base
{
public:void Fun(int x){cout<<"SubClass::Fun(int x)"<<endl;}void Fun(double x){cout<<"SubClass::Fun(double x)"<<endl;}virtual void G(void){cout<<"SubClass::G(void)"<<endl;}
};int main()
{Base *base = new Base();SubClass *subclass = new SubClass();base = subclass; //基类指针指向子类对象测试函数调用base->Fun(5);base->Fun(5.0);base->G();//subclass->Fun(20);//subclass->Fun(30.0);return 0;
}


输出结果


分析:

1. 定义一个基类Base,基类内部有两个重载函数Fun和一个虚函数G

2. 子类SubClass继承了基类Base,子类首先隐藏了基类的两个函数Fun并且覆盖了基类虚函数G;

    如果基类函数是虚函数,那么子类重新定义就属于覆盖。

    如果基类函数不是虚函数,那么子类重新定义属于隐藏基类函数

3. main函数内部,基类指针base指向子类对象指针subClass,然后调用三个函数

   (1)base->Fun(5) 输出“Base::Fun(int x)”说明调用的是基类的函数,可以看出通过基类指针并不能动态的调用子类覆盖基类的非虚函数

   (2)base->Fun(5.00) 和上面类似

   (3)base->G() 输出"SubClass::G(void)" 说明调用的是子类的函数G,可以看出通过基类指针可以动态的调用子类覆盖基类的虚函数


由此可见,多态的实现是通过子类覆盖基类的虚函数,利用基类指针指向不同的子类对象,在运行的时候动态的决定要调用哪个子类虚函数。



第二篇讲解文章

本文实例讲述了C++中重载、重写(覆盖)和隐藏的区别,对于C++面向对象程序设计来说是非常重要的概念。具体分析如下:

1.重载:重载从overload翻译过来,是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型


class TT
{
public:void test(int i);void test(double i);void test(int i, double j);void test(double i, int j);int test(int i); //错误,非重载
};


前四个互为重载函数,最后一个和第一个不是重载函数。

2.隐藏:隐藏是指派生类的函数屏蔽了与其同名的基类函数。注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏

实例代码如下:


class QQ
{
public:void fun1(int i, int j){cout << "A::fun1():" << i << " " << j << endl;}
};
class BB:public QQ
{
public:void fun1(double i)//隐藏{cout<<"B::fun1(): "<< i << endl;}
};
int main()
{BB b;b.fun1(5); //调用B类中的函数b.fun1(1,2); //error,因为基类函数被隐藏return 0;
}


?

3.重写:重写翻译自override,也翻译成覆盖(更好一点),是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰

实例代码如下:

class C1
{
public:virtual void fun3(int i){cout << "A::fun3(): " << i << endl;}
};
class C2:public C1
{
public:virtual void fun3(double i)//达不到基类虚函数的覆盖,因为参数列表不同{cout << "B::fun3(): "<< i << endl;}
};
int main()
{C1 c1;C2 c2;C1 *p1 = &c1;p1->fun3(3); //调用基类函数p1 = &c2;p1->fun3(5); //调用基类函数getchar();
}


?

上面为虚函数实现多态的代码,不明白的先看虚函数实现多态的原理。

重载和重写的区别:

(1)范围区别:重写和被重写的函数在不同的类中,重载和被重载的函数在同一类中

(2)参数区别:重写与被重写的函数参数列表一定相同,重载和被重载的函数参数列表一定不同

(3)virtual的区别:重写的基类必须要有virtual修饰,重载函数和被重载函数可以被virtual修饰,也可以没有

隐藏和重写,重载的区别:

(1)与重载范围不同:隐藏函数和被隐藏函数在不同类中

(2)参数的区别:隐藏函数和被隐藏函数参数列表可以相同,也可以不同,但函数名一定同;当参数不同时,无论基类中的函数是否被virtual修饰,基类函数都是被隐藏,而不是被重写

调试运行如下代码:

class RR
{
public:void fun1(int i, int j){cout << "A::fun1(): "<< i << " " << j << endl;}void fun2(int i){cout << "A::fun2(): " << i << endl;}virtual void fun3(int i){cout << "A::fun3(int): " << i << endl;}
};class DD:public RR
{
public:void fun1(double i)//隐藏{cout<<"B::fun1() :"<< i << endl;}void fun3(int i)//重写{cout<<"B::fun3(int): "<< i << endl;}void fun3(double i)//隐藏{cout<<"B::fun3(double): "<< i << endl;}
};int main()
{DD d;RR *pr = &d;DD *pd = &d;pr->fun3(3);//重写,多态性,调用RR的函数d.fun3(10); //隐藏,调用DD的函数pd->fun3(20); //隐藏,调用DD的函数getchar();return 0;
}


?

链接:http://m.blog.csdn.net/blog/cgl1079743846/27314745
http://www.jb51.net/article/54225.htm


这篇关于覆盖(override)和重载(overload)的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/898369

相关文章

native和static native区别

本文基于Hello JNI  如有疑惑,请看之前几篇文章。 native 与 static native java中 public native String helloJni();public native static String helloJniStatic();1212 JNI中 JNIEXPORT jstring JNICALL Java_com_test_g

最大流=最小割=最小点权覆盖集=sum-最大点权独立集

二分图最小点覆盖和最大独立集都可以转化为最大匹配求解。 在这个基础上,把每个点赋予一个非负的权值,这两个问题就转化为:二分图最小点权覆盖和二分图最大点权独立集。   二分图最小点权覆盖     从x或者y集合中选取一些点,使这些点覆盖所有的边,并且选出来的点的权值尽可能小。 建模:     原二分图中的边(u,v)替换为容量为INF的有向边(u,v),设立源点s和汇点t

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

POJ3041 最小顶点覆盖

N*N的矩阵,有些格子有物体,每次消除一行或一列,最少要几次消灭完。 行i - >列j 连边,表示(i,j)处有物体,即 边表示 物体。 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;impo

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

javascript中break与continue的区别

在javascript中,break是结束整个循环,break下面的语句不再执行了 for(let i=1;i<=5;i++){if(i===3){break}document.write(i) } 上面的代码中,当i=1时,执行打印输出语句,当i=2时,执行打印输出语句,当i=3时,遇到break了,整个循环就结束了。 执行结果是12 continue语句是停止当前循环,返回从头开始。

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们

ActiveMQ—Queue与Topic区别

Queue与Topic区别 转自:http://blog.csdn.net/qq_21033663/article/details/52458305 队列(Queue)和主题(Topic)是JMS支持的两种消息传递模型:         1、点对点(point-to-point,简称PTP)Queue消息传递模型:         通过该消息传递模型,一个应用程序(即消息生产者)可以

深入探讨:ECMAScript与JavaScript的区别

在前端开发的世界中,JavaScript无疑是最受欢迎的编程语言之一。然而,很多开发者在使用JavaScript时,可能并不清楚ECMAScript与JavaScript之间的关系和区别。本文将深入探讨这两者的不同之处,并通过案例帮助大家更好地理解。 一、什么是ECMAScript? ECMAScript(简称ES)是一种脚本语言的标准,由ECMA国际组织制定。它定义了语言的语法、类型、语句、