C++ 函数重写

2025年8月29日 | 阅读 7 分钟

在 C++ 中,函数重写是面向对象编程 (OOP) 的一个概念,它允许派生类重新定义其基类中已有的函数。它用于实现运行时多态性。

当我们需要修改或扩展继承函数的行为而不改变基类本身时,函数重写特别有用。它使我们能够提供该函数的特定实现,而该函数已由其基类提供。

语法

它具有以下语法:

在此语法中,函数名称、参数和返回类型函数是相同的。

C++ 函数重写示例

让我们看一个 C++ 中函数重写的简单示例。在此示例中,我们重写了 eat() 函数。

示例

编译并运行

输出

Eating bread...

C++ 中函数重写的规则

C++ 中函数重写的一些规则如下

  • 相同的函数名: 派生类中的函数应与基类中的函数同名。
  • 相同的参数: 函数签名(参数和返回类型)在两个类(基类和派生类)中都应相同。
  • 继承要求: 派生类必须继承自基类。
  • virtual 关键字: 如果基类中的函数声明为 virtual,它将确保正确的函数重写并允许动态调度。
  • 访问修饰符限制: 访问修饰符可以更改,但不建议这样做。

C++ 中函数重写的工作原理是什么?

在 C++ 中,函数重写取决于继承和 virtual 关键字的使用。当基类被指定为 virtual 时,它会指示编译器允许动态调度,这意味着函数调用在运行时根据对象类型而不是指针类型进行解析。

如果派生类对象重写基类虚函数,并且该函数通过基类指针或引用在运行时调用,则执行派生类版本的函数。此技术是使用编译器内部维护的虚表 (vtable) 实现的。

C++ 带有访问修饰符的函数重写示例

让我们再举一个例子来说明 C++ 中带有访问修饰符的函数重写。

示例

编译并运行

输出

Starting a car with a push button...

说明

在此示例中,我们使用了一个 vehicle 类(基类),其中包含一个 startEngine() 函数,该函数显示“正在启动通用车辆”。之后,car 类(派生类)继承自 vehicle 并重写了 startEngine() 函数。

之后,我们创建了一个 Vehicle* 类型的指针并将其分配给一个 car 对象。由于 startEngine() 函数是 virtual 的,因此在运行时动态调用 Car 类中被重写的函数,而不是基类函数。

在 C++ 中访问被重写的函数

有几种方法可以在派生类中访问被重写的函数,例如直接从对象访问,以及通过指针引用从基类访问。其中一些方法如下:

1. 直接从派生类调用被重写的函数

我们可以通过使用派生类对象直接从派生类调用被重写的函数。它调用在派生类中重新定义的函数。

直接从派生类调用被重写的函数示例

示例

编译并运行

输出

It is the derived class display function
It is the base class display function

说明

在此示例中,object.display() 函数调用派生类中被重写的函数,而 obj.callBaseFunction() 函数直接在派生类中调用基类版本的 display() 函数。

2. 通过基类指针或引用调用被重写的函数

当我们使用基类指针或引用调用函数,并且该函数在派生类中被重写时,程序中会调用该函数的派生类版本。

通过基类指针和引用调用被重写的函数示例

示例

编译并运行

输出

Brand Name: Mahindra
Brand Name: Kia
Brand Name: Kia

说明

在此示例中,基类 Car 定义了一个虚函数 showBrand()。Mahindra 和 Kia 品牌重写该函数以提供品牌特定的输出。使用基类指针和引用允许我们根据实际对象而不是指针和引用类型在运行时调用被重写的函数。

3. 使用作用域解析运算符调用被重写的函数

我们可以使用作用域解析运算符 (::) 在 C++ 中访问被重写的函数。

使用作用域解析运算符调用被重写的函数示例

示例

编译并运行

输出

This is the Derived Function.
This is the Base Function.

函数重写的优缺点

C++ 中函数重载的一些优缺点如下

优点

  • 函数重写提供了运行时多态性选项,可实现灵活的动态代码。
  • 它有助于节省内存空间。
  • 它使代码重用变得更容易。
  • 在函数重写中,子类可以访问父类的函数。
  • 我们可以专门化基类函数的继承行为以满足特定类。

缺点

  • 静态函数永远不能被重写。
  • 它不能在同一个类中执行。因此,我们需要实现继承。

C++ 函数重写 MCQ

1. 以下关于 C++ 中函数重写的说法哪一项是正确的?

  1. 仅当存在多个函数时才需要继承。
  2. 重写可以在不使用继承的情况下应用。
  3. 在程序中使用重写时不需要继承。
  4. 必须使用继承才能使用函数重写。
 

答案: d) 必须使用继承才能使用函数重写。


2. 在 C++ 中,我们如何从派生类访问基类的被重写方法?

  1. 使用点运算符
  2. 使用作用域解析运算符
  3. 使用箭头运算符
  4. 一旦被重写就无法访问
 

答案: b) 使用作用域解析运算符


3. C++ 中哪个关键字用于实现运行时多态性?

  1. virtual
  2. override
  3. static
  4. friend
 

答案: a) virtual


4. 以下代码的输出是什么?

  1. 这是基函数
  2. 这是派生函数
  3. 编译错误
  4. 运行时错误
 

答案: b) 这是派生函数


5. C++ 中基类的私有成员函数可以被重写吗?

  1. A) 是
  2. B) 否
  3. C) 仅当声明为 virtual 时
  4. D) 仅当声明为 public 时
 

答案: b) 否


下一主题C++ 虚函数