1、什么是函数重载?
重载:是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。
重载是多态性的一种表现。重载是指在一个类中定义了多个同名的方法,但他们的参数列表是不同的,也就是说有不同的参数个数或有不同类型的参数类型。
注意事项:
重载是通过方法中参数的不同来区分的,包含参数个数、参数类型、参数顺序等等。
如果父类方法访问权限为private,那么子类就不能对其进行重载;如果子类写了这个同名的方法,那只是定义了一个与父类方法相同的新方法,并不会得到重载的效果。
#include<bits/stdc++.h>
using namespace std;
class A
{
void fun() {};
void fun(int i) {};
void fun(int i, int j) {};
};
2、什么是函数重写?
重写(覆写):是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。
子类继承父类,子类重写父类中的所有公共方法,覆盖父类的方法并对其重写。
注意事项:
重写前后方法名相同;参数列表相同; 返回值相同;
子类重写的方法所抛出的异常必须与父类中的被重写方法的异常一致,或者不能比父类的异常范围更大。
父类的私有方法不能被重写,如果子类非要写这个同名方法,只是定义了一个与父类方法相同的新方法,而并不是重写父类的方法。
子类重写方法的访问权限不能低于父类方法中的访问权限,即子类的访问权限可以>=父类。j举个例子:父类是public 子类也可以是public,但是不可以是private;父类是private,子类可以是public或者private等等,只要比private权限大的都可以。
#include<bits/stdc++.h>
using namespace std;
class A
{
public:
virtual void fun()
{
cout << "A";
}
};
class B :public A
{
public:
virtual void fun()
{
cout << "B";
}
};
int main(void)
{
A* a = new B();
a->fun();//输出B
}
3、重载(overload)和重写(override)的区别?分别应用在什么场景?
(1)范围的区别:被重写和重写的函数在两个类中,重载和被重载的函数在同一个类中。
(2)参数的区别:重写与被重写的函数参数列表一定相同,重载和被重载的函数参数列表一定不同。
(3)virtual的区别:重写的基类中被重写函数必须要有virtual修饰,而重载函数和被重载函数可以被virtual修饰,也可以没有。
(4)定义的区别:重载是定义相同的方法名,参数不同;重写是子类重写父类的方法。
(5)多态性的区别:重载是编译时的多态性,重写是运行时的多态性。
(6)返回不同:重载对返回类型没有要求,而重写要求返回类型必须相同。
「注意」:虽然重载和覆盖都是实现多态的基础,但是两者实现的技术完全不相同,达到的⽬的也是完全不同的,覆盖是动态绑定的多态,而重载是静态绑定的多态。
应用场景:
在类中,要以统一的方式处理不同类型数据的时候,可以用重载。重载是多样性,是多态类型的演示,不修改原方法及源代码的基础上对方法进行扩展或增强时,使用重写。
重写的前提是继承,子类继承父类,子类才可以继承父类中的公有方法,增加新的功能、在原有的代码基础上对方法进行扩展和增强,需要用重写,提高了程序的多样性。重写时,参数列表,返回值得类型不能修改,异常可以减少或者删除,不能抛出新的异常或者比父类异常更广的异常,方法的访问权限可以降低,但是不能比父类权限高。
重载是构造器的重载,构造器重载后,提供多种形参形式的构造器,可以应对不同的业务需求,加强程序的健壮性和可扩展性。重载必须要修改方法(构造器)的形参列表,可修改返回值类型,也可修改访问权限(异常);使用范围是在同一个类中,目的是对构造器进行功能扩展,以应对多业务场景的不同使用需求。
4、类成员函数的隐藏与重写、重载的区别?
1、与重载的范围不同:和重写⼀样,隐藏函数和被隐藏函数不在同⼀个类中。
2、参数的区别:隐藏函数和被隐藏的函数的参数列表可以相同,也可以不同,但是函数名肯定要相同。当参数不相同时,无论基类中的参数是否被virtual 修饰,基类的函数都是被隐藏,而不是被重写。
类成员函数的重载、覆盖和隐藏区别?
答案:
a.成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)
5、C语言支持函数重载吗?为什么?
答:C语言不支持,因为C语言编译器对函数名修饰规则:仅仅只是在函数名前加_,这样编译器在调用时就无法区分函数名相同参数列表不同的函数了。
6、C++底层是怎么支持函数重载的?
(函数重载如何确定到底应该调用哪个函数?编译期间还是运行期间?)
答:C++编译器对函数名字修饰规则:编译器将参数类型信息增加到名字中了,这样即使函数名相同,只要参数类型不同,其在底层的名字就不同,编译器根据所传递参数在编译期间就可以确定到底应该调用哪个函数。
7、如果两个函数仅仅是因为返回值不同,为什么不能形成重载?
答:不能,比如:两个Add函数,参数都是int类型,一个返回int,一个返回double,如果按照Add(1,2),应该调用哪个重载函数呢?编译器就无法通过参数来确定了,因此报错。
8、函数重载与类模板的区别
(1)函数重载指的是在同一个作用域下,函数的名字相同,参数列表不同。它的底层是名字碾碎机制;类模板是建立一个通用的类,类中的成员、数据类型可以不具体指定,用一个虚拟的类型来代表。
(2)作用的对象不同:函数重载对应的是函数,类模板对应的是类。
(3)函数重载需要事先在函数列表中注明形参的类型,类模板可以不指定,在实例化对象的时候再指明对象即可。