C++ 函数重载与函数重写的区别

2024年8月28日 | 阅读 7 分钟

函数重载函数重写都是面向对象编程(OOPs)中实现代码重用灵活性的重要组成部分。尽管它们听起来可能相似,但这两个概念在根本上是不同的。本博客旨在为读者提供对C++ 函数重载函数重写的全面理解。我们将通过定义、语法、代码示例输出来展示这些差异。我们还将提供一个表格比较来突出这两个概念之间的区别。

函数重载

C++ 语言的函数重载功能允许具有相同名称的多个函数共存,前提是它们各自具有唯一的参数。它使程序员能够对各种数据类型或参数列表执行相关的操作。参数的数量、类型和顺序有助于编译器识别这些重载函数。

语法

以下是函数重载的语法:

示例

输出

Printing integer: 10
Printing double: 3.14

说明

在上面的示例中,我们定义了两个与打印相关的函数。而第二个打印函数需要一个双精度参数第一个打印函数只需要一个整数参数。编译器根据参数的类型区分这两个函数。当我们使用print(10)时,会调用带有整数参数的函数,并打印“Printing integer: 10”。为此,当我们使用print(3.14)时,会调用带有双精度参数的函数并打印“Printing double: 3.14”

函数重写

函数重写是在继承中使用的一个术语,其中派生类以独特的方式实现基类方法。它支持多态性,并允许在通过指向公共基类的指针或引用访问时一致地处理不同类的对象。

语法

以下是重写函数的语法:

示例

输出

Drawing a circle.

说明

在上面的示例中,我们有一个名为Shape基类和一个名为Circle派生类ShapeCircle类中都有一个名为draw()的方法。基类的实现仅打印“Drawing a shape”。派生类提供了该方法的不同实现,打印“Drawing a circle”。在main() 函数中,我们创建了一个Circle 对象并将其分配给一个Shape 指针。当我们通过基类引用调用draw() 方法时,会调用Circle类中被重写的方法,并打印“Drawing a circle”

函数重载与函数重写对比比较

在这里,您将学习函数重载和函数重写之间的对比比较。函数重载和函数重写之间的主要区别如下:

方面函数重载函数重写
范围同一类基类和派生类
是否需要继承不能是的
参数不同的参数相同的参数
多态行为不能是的
动态绑定不能是的

范围

函数重载:重载函数存在于同一个类中。

函数重写:基类派生类中都存在重写函数

是否需要继承

函数重载:不需要继承。重载可以在同一个类中进行。

函数重写:需要继承。将在派生类中重写的方法必须在基类中定义。

参数

函数重载:同一个类中的重载函数可以有不同的参数列表(数量、类型或顺序)。

函数重写:基类和派生类中的重写函数具有相同的参数列表(数量、类型和顺序)。

多态行为

函数重载:重载函数不显示多态行为。在编译时根据提供的参数确定合适的函数。

函数重写:重写函数实现了多态行为。根据实际对象类型,在运行时确定合适的函数。

动态绑定

函数重载:不需要动态绑定。编译器会根据输入在编译时决定使用哪个重载函数。

函数重写:重写函数使用动态绑定多态性是通过运行时根据实际对象类型选择相应函数来实现的。

编译器解析

函数重载:编译器在编译时根据传递给函数调用的参数来处理函数重载

函数重写:函数重写在运行时使用动态绑定来解析。

说明

范围

函数重载发生在同一个类中。在同一个类中,可以存在名称相同但参数不同的多个函数。这使得开发人员能够对不同的数据类型或使用不同的参数列表执行相关的操作。

函数重写同时支持基类派生类。派生类对基类中已定义的某个方法提供自定义的实现。它允许在通过指向公共基类的指针或引用访问时一致地处理不同类的对象。

是否需要继承

函数重载不需要继承。在同一个类中,重载函数可能存在,而与它们之间没有任何关联。

但是,函数重写需要继承。将在派生类中重写的方法必须在基类中定义。派生类继承了基类中的函数,并提供了自己的实现。

参数

函数重载是在同一个类中定义多个同名但参数列表不同的函数。参数在数量、类型顺序上可能有所不同。它在处理其他参数或数据类型时执行类似过程方面提供了灵活性。

为了被视为函数重写,派生类中的重写函数必须具有与基类中的相应函数相同的参数列表。参数在数量、类型顺序上必须完全匹配。通过基类指针或引用调用函数时,它确保行为的一致性。

多态行为

函数重载的行为不是多态的。在编译时,根据传递给函数调用的参数来查找合适的重载函数。在不考虑实际对象类型的情况下,选择是静态确定的。

函数重写实现了多态行为。通过基类指针或引用,它允许对不同类的对象进行统一处理。根据实际对象类型,在运行时确定合适的重写函数。这种动态耦合促进了扩展性和运行时灵活性。

动态绑定

动态绑定不是函数重载的一部分。编译器在编译时决定最适合的重载函数。根据函数调用时提供的参数,它会选择调用哪个函数。

动态绑定用于函数重写。在运行时,会选择相应的重写函数。选择是根据实际对象类型进行的,这支持运行时多态和后期绑定。

编译器解析

编译器在编译时处理函数重载。根据参数的数量、类型顺序,编译器将传递给函数调用的参数与相应的重载函数进行匹配。

另一方面,函数重写是在运行时解析的。根据实际的对象类型,动态选择合适的重写函数。虚拟函数表和虚拟函数指针在后台用于实现这种运行时解析。

结论

总之,函数重载函数重写是 C++ 的两个重要特性,它们提高了灵活性和代码重用性。尽管它们的语法以及拥有多个同名函数这一概念可能相似,但两者之间存在显著的差异。

程序员可以通过函数重载在同一个类中定义多个同名但参数列表不同的函数。因此,可以根据提供的参数在编译时选择正确的函数。通过允许对其他数据类型或不同的参数列表执行等效操作,它提供了简单性和多功能性。

另一方面,多态性继承都使用函数重写。当派生类实现了基类中已定义的某个方法时,就会发生这种情况。它允许在通过指向公共基类的指针引用访问时一致地处理不同类的对象。动态绑定通过函数重写得到体现,这意味着根据实际对象类型在运行时选择正确的方法。

在构建高效、可维护的 C++ 代码时,理解函数重载函数重写之间的区别至关重要。通过明智地利用这些特性,开发人员可以构建健壮、适应性强的程序,以满足不同的需求并促进代码重用。