Virtual functions in C++ are member functions of a base class that can be replaced (overridde
n) by member functions of a derived class .
They are declared using the virtual
keyword in the base class.
The main purpose of virtual functions is to allow runtime polymorphism, that is, to allow the call to a member function to be resolved at runtime based on the type of the object for which the function is being called, rather than the type of the reference or pointer being used to access the object.
Here are some examples to illustrate the concept of virtual functions:
Note: Virtual member functions DOES NOT WORK WITH TEMPLATE, and of course, they only work in Object Oriented Programming!
See in this example that the Derived
class inherits the public
members (and if there were, the protected
ones too) from the Base
class.
Note that both have the member function: void show()
, and even using ponteiros(regardless of whether or not smart pointers, it’s the same thing) to create the object, when calling show()
, the content of Base
is what is displayed:
Output after compiling and running g++ nao-virtual.cpp && ./a.out
:
To be able to display the show()
of the Derivative
, we simply had to declare the show()
of the Base
as virtual
, but to know that we are overwriting a virtual member function, the correct thing is to also declare the ` show() of the
Derivative with the
overridde` keyword, that is, our code would look like this:
NOTE: Only in cases where the object is created with pointers, as stated above!
Now yes, the output after compiling and running g++ nao-virtual.cpp && ./a.out
will be the show()
of the Derivative
:
This concept is also widely used as Virtual Destructors, that is, so your software does not keep calling multiple Destructors recursively. So notice that I declared: ~Base() = default
, but if we had declared it as: virtual ~Base();
, the Derivative
destructor, if there was one, would prevail!
This is also important to avoid memory leaks and other problems related to proper resource cleaning, especially in cases of multiple class hierarchies, e.g.:
class Shape(); → class RectangleShape(); → class SquareShape();
.
Virtual functions are a fundamental mechanism for polymorphism in C++ and allow you to write more flexible and extensible code.
Another concept in C++ is Function Overloading, which in short is: “Use functions with the same name, but with different parameter types, but just difference in return type, no!”.
Example, note that below we have the show()
functions with the same name but different types of parameters:
This compiles and runs!
However, if we had this function:
It will not compile, because despite having a different return type: void
, it has the same arguments as a function that already exists, which is: std::string show(const std::string& str, int c);
.
This also works for member functions in Object Oriented Programming!
Note that Virtual Functions is TOTALLY different from Function Overloading. Perhaps the similarity that some may see is the fact of using the same function name.