what's the purpose of having a base class |
Strictly speaking, you don't need them. C has gotten by without classes completely. :)
But the benefits of of having a base class could be to (1) avoid code duplication, and (2) to allow for run-time polymorphism via virtual functions. Also, there's the curiously recurring template pattern,
https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern but I won't discuss that here since I've hardly ever used it, maybe someone else wants to.
(1) Let's say you have a Thing class that has {a, b, c} variables. ThingExtra class has {a, b, c, d} variables. Instead of creating two independent classes, you could just have,
1 2
|
class Thing { int a, b, c; };
class ThingExtra : public Thing { int d; };
|
(2) Have you used polymorphism in your studies yet? One of the biggest places you'll see inheritance used is in combination with run-time polymorphism.
Let's say, both Dog and Cat derive from Animal, and you have a container of Animal pointers.
You can iterate through the container and call a virtual function on the base-class pointer which then calls the corresponding sub-class function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
// Example program
#include <iostream>
using std::cout;
class Animal {
public:
virtual void hello() const =0;
};
class Dog : public Animal {
public:
void hello() const override
{
cout << "Woof!\n";
}
};
class Cat : public Animal {
public:
void hello() const override
{
cout << "Meow!\n";
}
};
#include <vector>
int main()
{
Cat cat;
Dog dog;
std::vector<Animal*> animals { &cat, &dog };
for (const auto& animal : animals)
{
animal->hello();
}
}
|
Run-time polymorphism determines (at run-time) that the first Animal pointer is pointing to a Cat, and the second Animal pointer is pointing to a Dog, and calls the corresponding overridden functions. Run-time polymorphism can also be done through references, although you can't directly store a reference in a container.