三重-------函数重载,函数重写(同名覆盖),函数重定义(同名隐藏)

一,函数重载

  • 直接上图吧!
    三重-------函数重载,函数重写(同名覆盖),函数重定义(同名隐藏)_第1张图片
  • 概念:函数重载是一种特殊情况,C++允许在同一作用域中声明几个类似的同名函数,这些同名函数的形参列表(参数个数,类型,顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。

实现原理

  • 为什么C语言不支持函数重载,c++却支持函数重载,简单来说,也就是两种语言对函数后期函数名修饰规则不同,
C语言的函数名修饰规则
int Add(int x, int y)
{
	return x+y;
}
  • 这是一个简单的求两数之和的函数,在C语言中,编译器会在函数名处理成_Add,就是简单的在本身的函数名前加一个"_",假如有多个同名的函数,编译器识别不了到底是哪个函数,所以C语言不支持函数重载。
c++的函数名字修饰规则
  • c++会将上面的函数修饰成**?Add@@YAHHH@Z **(各个版本不同),那么这些符号表示什么意思是呢?
  • 其中‘?’标识函数名的开始,其后跟函数名,“@@YA”标识参数表的开始,其后跟的第一个字符代表函数的返回值类型,接下来的字符依次代表函数参数列表中各个参数的类型;
  • 各个类型的代号:
    三重-------函数重载,函数重写(同名覆盖),函数重定义(同名隐藏)_第2张图片
  • 所以@@yg后面的HHH分别代表三个int类型,其中第一个为函数返回值,上下两个为参数类型,@z标识整个名字结束。
  • 这样以来,c++处理函数名字的时候,把参数的不同也加入到函数名字修饰规则之中,因此不同的参数的同名函数,我们表面上看函数名字相同,其实编译器可以辨别出,
函数重载的作用
  • 减少了函数名的数量,避免出现重定义,避免了命名污染;
  • 提高程序可读性。
  • 在编译期间根据参数的不同就能决定调用哪一个函数,叫做静态重载。

二,函数重写

  • 概念派生类基类同名虚函数的改写就叫函数重写
  • 分析:1,函数重载发生在子类和父类之间, 2,父类中含有虚函数(virtual修饰的函数),3,子类中含有同父类虚函数相同原型的函数,4,只有在运行期间才能决定调用哪一个函数,叫做动态重载
实列分析

三重-------函数重载,函数重写(同名覆盖),函数重定义(同名隐藏)_第3张图片

  • 上面的例子涉及到一个小知识,就是赋值兼容规则,在第二次调用Func函数的时候,我传的实际参数为派生类对象,但是Func函数本身的形参是基类的引用,依据派生类的对象模型可以知道,基类的引用或者指针可以赋值或者指向派生类的对象,
赋值兼容规则
  • 基类的指针,引用可以指向派生类的对象;
  • 派生类的对象可以赋值给基类,基类的对象不可以赋值给派生类;
  • 基类的指针可以通过强制类型转换赋值给派生类的指针。但是必须是基类的指针是指向派生类对象时才是安全的。
虚函数重写的例外:协变
  • 概念:重写的虚函数的返回值可以不同,但是必须分别是基类指针和派生类指针或者基类
    引用和派生类引用

三,函数重定义(同名隐藏)

  • 概念:派生类的函数屏蔽了与其同名的基类函数
  • 分析:1,首先也是基于继承体系中的, 2,基类和派生类中有同名的函数,3,在调用这个函数的时候,用派生类对象调用只会调用自己的函数,基类的同名函数被隐藏。
实例分析

三重-------函数重载,函数重写(同名覆盖),函数重定义(同名隐藏)_第4张图片

  • 还是刚才的代码,通过派生类调用同名函数,会调用到自己的,要是调用基类的函数,需要加作用于限定符。

四,总结

函数重载条件
  • 发生在同一作用域
  • 只有函数名字相同
  • 参数列表不同(参数类型,个数,顺序)
  • const也可以构成重载,
  • 全缺省函数和无参数的函数也可以构成重载(最好只出现一个)
  • 与函数的返回类型无关
函数重写条件
  • 发生在不同作用域,一个函数在基类,一个函数在派生类
  • 函数名字和参数必须相同(参数相同,返回值相同)
  • 基类的同名函数是虚函数(有virtual修饰)
  • 派生类要对同名函数进行改写,
函数重定义(同名隐藏)
  • 发生在不同作用域,一个在基类,一个在派生类;
  • 基类和派生类具有同名函数(仅仅函数名字相同)
  • 派生类要调用这个函数时,只会调用自己的,会把基类的同名函数隐藏起来
  • 要调用基类的同名函数,需要加作用于限定符
欢迎大家来指正

你可能感兴趣的:(c++)