目录
一、函数重载(重定义)
1、函数重载:
重载是指函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(同名,参数类型、个数、顺序不同)。
对于重载函数的调用,在编译期间就已经确定,是静态的,它们的地址在编译期间就绑定了与多态无关。
2、函数重载在C语言中为啥不能共存
(1)C语言没有函数重载,重载是C++的内容
(2)C语言不能重载与函数编译后函数名有关
编译后函数名变化只是在原来的函数名前加了一个下划线,所以当同名的函数参数不同时,编译器是无法解析到它们的不同, 因为它们编译后的名称都相同,所以c语言不能函数重载
3、C++中函数重载
(1)返回值 //无关 返回值不参与重载
重载决议:调用点和定义点进行匹配:类型匹配
调用点只能看到函数名和实参,返回值不能做调用点的依据,因此也不能做函数重载的依据
(2)函数名 //无关
?Sum@@YAHHH@Z int H //函数符号生成不同
?Sum@@YANNN@Z double N
(3)形参: //有关
参数个数
参数类型
参数数据
4、函数重载的特点:(重载的三要素)
(1)同名
(2)不同参
(3)同作用域: //C++有就近原则
二、覆盖
1、覆盖函数:
覆盖是指派生类中存在重新定义基类的函数,其函数名、参数列、返回值类型必须同父类中的相对应被覆盖的函数严格一致,覆盖函数和被覆盖函数只有函数体不同,当派生类对象调用子类中该同名函数时会自动调用子类中的覆盖版本,而不是父类中的被覆盖函数版本,它和多态真正相关。
当子类重新定义了父类的虚函数后,父类指针根据赋给它不同的子类指针,动态地调用属于子类地该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的。
2、覆盖的特征:
(1)不同的范围(分别位于派生类和基类)
(2)函数名字相同
(3)参数相同
(4)基类函数必须有virtual关键字
三、重载和覆盖的区别
1、覆盖是子类和父类之间的关系,是垂直关系;重载是同一个类中方法之间的关系,是水平关系
2、覆盖只能由一个方法,或只能由一对方法产生关系;方法的重载是多个方法之间的关系
3、覆盖要求参数列表相同;重载要求参数列表不同
4、覆盖关系中,调用方法体是根据对象的类型(对相对应存储空间类型)来决定的;重载关系是根据调用时的实参表与形参表来选择方法体的
四、程序示例
#include<iostream>
using namespace std;
class Base
{
public:
void f(int x)
{
cout<<"Base::f(int)"<<x<<endl;
}
void f(float x)
{
cout<<"Base::f(float)"<<x<<endl;
}
virtual void g(int y)
{
cout<<"Base::g(int)"<<y<<endl;
}
};
class Derived:public Base
{
public:
virtual void g(int y)
{
cout<<"Derived::g(int)"<<y<<endl;
}
};
int main()
{
Derived d;
Base *pb = &d;
pb->f(42);
pb->f(3.14f);
pb->g(24);
return 0;
}
(1)函数Bse::f(int)与Base::f(float)相互重载;
(2)Base::g(void)与Derived::g(void)覆盖;