# C++ 中的虚函数：运行时多态

> 原文： [https://beginnersbook.com/2017/09/cpp-virtual-functions-runtime-polymorphism/](https://beginnersbook.com/2017/09/cpp-virtual-functions-runtime-polymorphism/)

在本指南中，我们将看到**什么是虚函数以及我们使用它们的原因**。当我们在一个类中将一个函数声明为虚函数时，所有覆盖此函数的子类默认情况下的函数实现为虚函数（无论它们是否标记为虚拟）。

**为什么我们声明一个虚函数？** 

让编译器知道需要在运行时解析对此函数的调用（也称为**晚期绑定**和动态链接），以便确定对象类型并且调用函数的正确版本。

让我们举个例子来理解当我们不将[覆盖函数](https://beginnersbook.com/2017/09/cpp-function-overriding/)标记为虚拟时会发生什么。

## 示例 1：覆盖非虚函数

在这里看到问题。即使我们指向子类的实例（对象）的父类指针，也会调用该函数的父类版本。

您可能在想我为什么创建指针，我可以简单地创建子类的对象，如下所示：`Dog obj;`并将`Dog`实例分配给它。好吧，在这个例子中我只有一个子类，但是当我们有一个包含多个子类的大项目时，不建议单独创建子类的对象，因为它增加了复杂性并且代码容易出错。在此示例之后更加清晰。

```cpp
#include<iostream>
using namespace std;
//Parent class or super class or base class
class Animal{
public:
   void animalSound(){
      cout<<"This is a generic Function";
   }
};
//child class or sub class or derived class
class Dog : public Animal{
public:
   void animalSound(){ 
      cout<<"Woof";
   }
};
int main(){
   Animal *obj;
   obj = new Dog();
   obj->animalSound();
   return 0;
}
```

**输出：**

```cpp
This is a generic Function
```

## 示例 2：使用虚函数

在这种情况下，输出是`Woof`，这是我们所期望的。在这种情况下会发生什么？由于我们将函数`animalSound()`标记为虚拟，因此在运行时解析对函数的调用，编译器在运行时确定对象的类型并调用适当的函数。

```cpp
#include<iostream>
using namespace std;
//Parent class or super class or base class
class Animal{
public:
   virtual void animalSound(){
      cout<<"This is a generic Function";
   }
};
//child class or sub class or derived class
class Dog : public Animal{
public:
   void animalSound(){ 
      cout<<"Woof";
   }
};
int main(){
   Animal *obj;
   obj = new Dog();
   obj->animalSound();
   return 0;
}
```

输出：

```cpp
Woof
```