一尘不染

为什么我们需要 C++ 中的虚函数?

c++

我正在学习 C++,我刚刚进入虚拟函数。

从我读到的(在书中和在线)中,虚函数是基类中的函数,您可以在派生类中覆盖它们。

但是在本书的前面,在学习基本继承时,我能够在派生类中重写基函数,而无需使用virtual.

那么我在这里错过了什么?我知道虚函数还有更多,而且它似乎很重要,所以我想弄清楚它到底是什么。我只是无法在网上找到一个简单的答案。


阅读 149

收藏
2022-02-23

共1个答案

一尘不染

以下是我不仅理解什么是virtual功能,而且理解为什么需要它们的方式:

假设你有这两个类:

class Animal
{
    public:
        void eat() { std::cout << "I'm eating generic food."; }
};

class Cat : public Animal
{
    public:
        void eat() { std::cout << "I'm eating a rat."; }
};

在您的主要功能中:

Animal *animal = new Animal;
Cat *cat = new Cat;

animal->eat(); // Outputs: "I'm eating generic food."
cat->eat();    // Outputs: "I'm eating a rat."

到目前为止一切顺利,对吧?动物吃普通食物,猫吃老鼠,都没有virtual

现在让我们稍微改变一下,以便eat()通过中间函数调用(对于这个例子来说是一个微不足道的函数):

// This can go at the top of the main.cpp file
void func(Animal *xyz) { xyz->eat(); }

现在我们的主要功能是:

Animal *animal = new Animal;
Cat *cat = new Cat;

func(animal); // Outputs: "I'm eating generic food."
func(cat);    // Outputs: "I'm eating generic food."

哦哦……我们把一只猫传给了func(),但它不会吃老鼠。你应该超载func()所以它需要一个Cat*?如果你必须从 Animal 派生出更多的动物,它们都需要自己的func()

解决方案是eat()Animal类中创建一个虚函数:

class Animal
{
    public:
        virtual void eat() { std::cout << "I'm eating generic food."; }
};

class Cat : public Animal
{
    public:
        void eat() { std::cout << "I'm eating a rat."; }
};

主要的:

func(animal); // Outputs: "I'm eating generic food."
func(cat);    // Outputs: "I'm eating a rat."
2022-02-23