Jake Wilson Jake Wilson - 3 months ago 8
C++ Question

Why do we need Virtual Functions in C++?

I'm learning C++ and I'm just getting into Virtual Functions.

From what I've read (in the book and online), virtual functions are functions in the a base class that you can override in derived classes.

But earlier in the book, when learning about basic inheritance, I was able to override base functions in derived classes without using

virtual
.

So what am I missing here? I know there is more to virtual functions and it seems to be important so I want to be clear on what it is exactly. I just can't find a straight answer online.

Answer

I'm a C++ newbie myself, but here is how I understood not just what virtual functions are, but why they're required:

Let's say you have these two classes:

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."; }
}

In your main function:

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

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

So far so good right? Animals eat generic food, cats eat rats, all without virtual.

Let's change it a little now so that eat() is called via an intermediate function (a trivial function just for this example):

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

Now our main function is:

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

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

Uh oh... we passed a Cat into func(), but it won't eat rats. Should you overload func() so it takes a Cat* ? If you have to derive more animals from Animal they would all need their own func().

The solution is to make eat() a virtual function:

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."; }
}

Main:

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

Done.