What is Virtual function? How does it work in C++?
In C++, a virtual function or virtual method is an inheritable and overridable function or method for which dynamic dispatch is facilitated. It's an important part of the runtime polymorphism portion of object-oriented programming. In short, a virtual function defines a target function to be executed, but the target might not be known at compile time. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class’s version of the function. Basically, Virtual Function is a function in base class, which is overridden in the derived class, and which tells the compiler to perform Late Binding on this function. Virtual Keyword is used to make a member function as a Virtual.
Now, what is Late Binding or Dynamic Binding?
In Late Binding, function call is resolved at runtime. Hence, compiler determines the type of object at runtime, and then binds the function call. Late Binding is also called Dynamic Binding or Runtime Binding.
To accomplish late binding, compiler creates vTables, for each class with virtual function. The address of virtual functions is inserted into these tables. Whenever an object of such class has created the compiler secretly inserts a vPointer, pointing to vTable for that object. Hence when function is called, compiler is able to resolve the call by binding the correct function using the vPointer.
What is vTable?
Every class that has one or more virtual member functions in it has a vTable associated with it. vTable is a kind of function pointer array that contains the addresses all virtual functions of this class. Compiler builds this vTable at compile time.
What is vPointer?
For every object of a class that has a vTable associated with it, contains a vPointer in first 4 bytes. This vPointer points to the vTable of that class. This vPointer will be used to find the actual function address from vTable at run time.
What is the use of Virtual function?
Virtual functions allow us to create a list of base class pointers and call methods of any of the derived classes without even knowing kind of derived class object.
In object-oriented programming, when a derived class inherits from a base class, an object of the derived class may be referred to via a pointer or reference of the base class type instead of the derived class type. If there are base class methods overridden by the derived class, the method actually called by such a reference or pointer can be bound either 'early' (by the compiler), according to the declared type of the pointer, according to the actual type of the object referred to.
Virtual functions are resolved 'late'. If the function is 'virtual' in the base class, the most-derived class's implementation of the function is called according to the actual type of the object referred to, regardless of the declared type of the pointer. If it is not 'virtual', the method is resolved 'early' and the function called is selected according to the declared type of the pointer.
Virtual functions allow a program to call methods that don't necessarily even exist at the moment the code is compiled.
In C++, virtual methods are declared by prepending the virtual keyword to the function's declaration in the base class. This modifier is inherited by all implementations of that method in derived classes, meaning that they can continue to override each other and be late-bound. And even if methods owned by the base class call the virtual method, they will instead be calling the derived method. Overloading occurs when two or more methods in one class have the same method name but different parameters.
How are virtual functions implemented at a deep level?
Whenever a program has a virtual function declared, a vTable is constructed for the class. The vTable consists of addresses to the virtual functions for classes that contain one or more virtual functions. The object of the class containing the virtual function contains a virtual pointer that points to the base address of the virtual table in memory. Whenever there is a virtual function call, the vTable is used to resolve to the function address. An object of the class that contains one or more virtual functions contains a virtual pointer called the vPointer at the very beginning of the object in the memory. Hence the size of the object, in this case, increases by the size of the pointer. This vPointer contains the base address of the virtual table in memory. Note that virtual tables are class specific, so, there is only one virtual table for a class irrespective of the number of virtual functions it contains. This virtual table, in turn, contains the base addresses of one or more virtual functions of the class. At the time when a virtual function is called on an object, the vpointer of that object provides the base address of the virtual table for that class in memory. This table is used to resolve the function call as it contains the addresses of all the virtual functions of that class. This is how dynamic binding is resolved during a virtual function call.