C ++中的函数重载与重载之间的区别
内容
在‘超载‘我们使用相同的函数名称,不同数量和类型的参数重新定义重载函数。在‘压倒一切在整个程序中,“覆盖功能的原型”都是相同的,但是要覆盖的功能在基类中以关键字“ virtual”开头,并由派生类重新定义而没有任何关键字。
多态性是OOP的关键特征之一。它只是意味着“为多个表单使用一个名称”。可以使用“功能重载”,“操作员重载”和“虚拟功能”来实现多态。 “重载”和“覆盖”都暗示着多态的概念。在这里,“重载”是编译时多态,“重载”是运行时多态。进一步研究,如果我们谈论“过载”和“覆盖”的主要区别。
此外,借助比较表,我们研究了重载和重载之间的区别。
- 比较表
- 定义
- 关键差异
- 相似点
- 结论
比较表:
比较基础 | 超载 | 覆写 |
---|---|---|
原型 | 原型会有所不同,因为参数的数量或类型可能会有所不同。 | 原型的所有方面都必须相同。 |
关键词 | 重载期间未应用任何关键字。 | 在基类中,要覆盖的函数前面有关键字virtual。 |
区别因素 | 参数的数量或类型不同,这决定了要调用的函数的版本。 | 指针调用哪个类的功能由分配给该指针的对象的类的地址确定。 |
定义模式 | 函数以相同的名称重新定义,但参数的数量和类型不同。 | 定义函数,在主类中以virtual关键字开头,然后由派生类使用out关键字重新定义函数。 |
完成时间 | 编译时间。 | 运行。 |
构造函数/虚拟函数 | 构造函数可以重载。 | 虚函数可以被覆盖。 |
析构函数 | 析构函数不能重载。 | 析构函数可以被覆盖。 |
捆绑 | 重载可实现早期绑定。 | 覆盖是指后期绑定。 |
重载的定义
编译时多态被称为“重载”。由于重载是由多态概念产生的,因此它提供了“多种方法的通用接口”。这意味着,如果一个函数被重载,则在重新定义该函数时它将包含相同的函数名。
重载函数的区别在于“参数的数量或类型”不同,这使得一个重载函数与另一个重载函数有所不同。这样,编译器可以识别正在调用哪个重载函数。最常见的重载函数是“构造函数”。 “复制构造函数”是一种“构造函数重载”。
用C ++实现重载
类重载{int a,b; public:int load(int x){//第一个load()函数a = x;返回} int load(int x,int y){//第二个load()函数a = x; b = y;返回a * b; }; int main(){重载O1; O1.load(20); //第一个load()函数调用O1.load(20,40); //第二个load()函数调用}
此处,类重载的函数load()已重载。可以通过以下方式区分该类的两个重载函数:第一个load()函数仅接受单个整数参数,而第二个load()函数则接受两个整数参数。当类重载的对象使用单个参数调用load()函数时,将首先调用load()函数。当对象调用传递两个参数的load()函数时,将调用第二个load()函数。
覆盖的定义
在运行时实现的多态称为“覆盖”。它是通过使用“继承”和“虚拟功能”来实现的。要覆盖的功能在基类中以关键字“ virtual”开头,并在派生类中重新定义而没有任何关键字。
在重写的情况下要记住的最重要的事情之一是,在派生类重新定义它时,重写的函数的原型一定不能更改。当调用覆盖函数时,C ++根据完成函数调用的“指针所指向的对象的类型”来确定调用哪个版本的函数。
C ++中重写的实现
class base {public:virtual void funct(){//基类cout的虚拟函数<<“这是基类funct()”; }; class Drawn1:public base {public:void funct(){//基类的虚函数在derived1中重新定义。class cout <<“这是一个derived1类funct()”; };类派生2:公共基{公共:void funct(){//在派生2类中重新定义的基类的虚拟函数类cout <<“这是一个派生2类funct()”; }; int main(){base * p,b;派生1 d1;派生2 d2; * p =&b; p-> funct(); //调用基类funct()。 * p =&d1; p-> funct(); //调用派生类class funct()。 * p =&d2; p-> funct(); //调用派生2类funct()。返回0; }
在这里,只有一个基类,该基类由两个派生类公开继承。在基类中使用关键字“ virtual”定义了虚函数,并且两个派生类都使用无关键字对其进行了重新定义。在main()中,基类创建一个指针变量“ p”和一个对象“ b”; “ derived1”类创建对象d1,而“ derived2”类创建对象d2”。
现在,最初将基类对象“ b”的地址分配给基类“ p”的指针。 “ p”调用了函数funct(),因此调用了基类的函数。然后将派生1类对象“ d1”的地址分配给指针“ p”,再次调用funct();。在此执行派生1类的函数funct()。最后,将指针“ p”分配给派生2类的对象。然后,“ p”调用函数funct(),该函数执行派生2类的函数funct()。
如果派生1 /派生2类未重新定义funct(),则将调用基类的funct(),因为虚拟函数是“分层的”。
- 由于传递给重载函数的参数的类型和数量,被重载的函数的原型有所不同。另一方面,覆盖函数的原型不会更改,因为覆盖函数对它所属的不同类执行不同的操作,但具有相同的参数类型和数量。
- 重载的函数名称不以任何关键字开头,而被覆盖的函数的名称仅在基类中以关键字“ Virtual”开头。
- 调用哪个重载函数取决于传递给该函数的参数的类型或数量。哪个类被调用的覆盖函数取决于哪个类的对象地址分配给了调用该函数的指针。
- 在编译期间解析要调用哪个重载函数。在运行时解析哪个覆盖的函数被调用。
- 构造函数可以重载,但不能被覆盖。
- 析构函数不能重载,但是可以被覆盖。
- 重载实现了早期绑定,因为将在编译时解决要调用的重载函数。覆盖实现了后期绑定,因为在运行时将解析将调用哪个覆盖的函数。
相似点
- 两者都应用于类的成员函数。
- 多态是两者背后的基本概念。
- 当我们对函数应用重载和重写时,函数名称保持不变。
结论
重载和重载看起来相似,但是事实并非如此。可以重载函数,但是任何类将来都不能进一步重新定义重载函数。虚拟函数不能重载;它们只能被覆盖。