I am learning c++ and am learning about the virtual keyword. I have scoured the internet trying to understand it to no avail. I went into my editor and did the following experiment, expecting it to print out the base message twice (because I was under the impression that the virtual keyword is needed to override functions). However, it printed out two different messages. Can someone explain to me why we need the virtual keyword if we can simply override functions and still seemingly get polymorphic behavior? Perhaps someone can help me and other people in the future understand virtual vs. overriding. (The output I am getting is "I am the base" followed by "I am the derived").
#include <iostream>
using namespace std;
class Base{
public:
void printMe(){
cout << "I am the base" << endl;
}
};
class Derived: public Base{
public:
void printMe(){
cout << "I am the derived" << endl;
}
};
int main() {
Base a;
Derived b;
a.printMe();
b.printMe();
return 0;
}
Consider the following example. The important line to illustrate the need for virtual
and override
is c->printMe();
. Note that the type of c
is Base*
, however due to polymorphism it is correctly able to call the overridden method from the derived class.
#include <iostream>
class Base{
public:
virtual void printMe(){
std::cout << "I am the base" << std::endl;
}
};
class Derived: public Base{
public:
void printMe() override {
std::cout << "I am the derived" << std::endl;
}
};
int main() {
Base a;
Derived b;
a.printMe();
b.printMe();
Base* c = &b;
c->printMe();
return 0;
}
The output is
I am the base
I am the derived
I am the derived
With the code you have, if you do this
Derived derived;
Base* base_ptr = &derived;
base_ptr->printMe();
What do you think happens? It will not print out I am the derived
because the method is not virtual, and the dispatch is done off the static type of the calling object (i.e. Base
). If you change it to virtual the method that is called will depend on the dynamic type of the object and not the static type.
You're not seeing the behaviour here because you've declared b
to be of type Derived
so the compiler knows what functions to use. In order to expose why virtual
is necessary you need to mix things up:
int main() {
Base a;
Base *b = new Derived();
a.printMe();
b->printMe();
delete b;
return 0;
}
Now b
is of type Base*
which means it's going to use the functions on Base
plus whatever's in the virtual function table. This breaks your implementation. You can fix it by properly declaring things virtual
.
override
is a new keyword added in C++11.
You should use it because:
the compiler will check if a base class contains a matching virtual
method. This is important since some typo in the method name or in its list of arguments (overloads are allowed) can lead to the impression that something was overridden when it really was not.
if you use override
for one method, the compiler will report an error if another method is overridden without using the override
keyword. This helps detect unwanted overrides when symbol collisions happen.
virtual
doesn't mean "override". In class doent use "override" keyword than to override a method you can simply write this method omitting "virtual" keyword, override will happen implicitly. Developers were writing virtual
before C++11 to indicate their intention of override. Simply put virtual
means: this method can be overridden in a subclasses.