Virtual function and virtual base class in C++
Virtual functions and virtual base classes are two crucial ideas utilized in C++ object-oriented programming to enable polymorphism and efficiently manage class hierarchies. In this article, we will discuss the virtual function and virtual base class in C++ with some key features, syntax, and examples.
1.Virtual function:
A virtual function is a member function that is designated with the keyword virtual in a base class. When a function is declared as virtual, the function call is resolved at runtime based on the type of the actual object because it permits dynamic dispatch or late binding.
Key ideas regarding virtual functions:
There are various key ideas regarding virtual functions in C++. Some main points are as follows:
- Through the use of virtual functions, polymorphism is made possible, allowing derived classes to override the implementation of a base class by providing their own.
- They are employed in a class hierarchy in which base classes define a common interface and derived classes implement particular behaviors.
- The override keyword is optional but advised for clarity in C++11 and later allows virtual functions to be overridden in derived classes. Virtual functions must be declared in the base class and can only be modified in those classes.
In C++, you must add the virtual keyword to the function's declaration in the base class to create a virtual function:
class Shape
{
public:
virtual void draw()
{
// Base class implementation.
// This function can be overridden in derived classes.
}
};
In derived classes, you can provide specific implementations for the virtual function, and the correct function will be called at runtime based on the actual object type:
class Circle : public Shape
{
public:
void draw() override
{
// Specific implementation for Circle.
}
};
class Square : public Shape
{
public:
void draw() override
{
// Specific implementation for Square.
}
};
Example:
Let's take a simple program to understand the use of virtual function in C++.
#include <iostream>
class Shape
{
public:
virtual void draw()
{
std::cout<< "Drawing a generic shape." <<std::endl;
}
};
class Circle : public Shape
{
public:
void draw() override
{
std::cout<< "Drawing a circle." <<std::endl;
}
};
class Square : public Shape
{
public:
void draw() override
{
std::cout<< "Drawing a square." <<std::endl;
}
};
int main()
{
Shape* shape1 = new Circle();
Shape* shape2 = new Square();
shape1->draw(); // Output: Drawing a circle.
shape2->draw(); // Output: Drawing a square.
delete shape1;
delete shape2;
return 0;
}
Output:
Drawing a circle.
Drawing a square.
Explanation:
With a virtual function called the draw() function, the base class in this illustration is called Shape. The Circle and Square classes are descended classes that override the draw() function to provide their particular implementations. Due to dynamic binding, the correct instance of draw() from the derived class is called at runtime when draw() is invoked through pointers to Shape.
2.Virtual Base Classes:
Consider the following: class A, class B, class C, and class D are the four classes in a C++ program. If class A's properties are passed down to class B and class C. After that, the class B and class C will pass their properties onto class D. As class D will have twice as many properties as class A, an error will appear when the code is run. The term "Virtual" is appropriate in this circumstance.
A base class that is virtually inherited by derived classes is known as a virtual base class in C++. The inheritance declaration uses the keyword "virtual" to specify that the inheritance must be virtual. When a class can inherit from several classes that have a common base class, the diamond problem is solved using this theory.
Important information concerning virtual base classes:
There are various key points regarding virtual base classes in C++. Some main points are as follows:
- The inheritance must be declared using the term virtual in the derived classes to build a virtual base class.
- Virtual inheritance is employed when you wish to make a commonly shared base class for classes that are not connected directly but indirectly inherit from a common ancestor.
Assume you have an Animal base class and the derived classes Dog and Bird. Now, you wish to develop the class FlyingDog, which will inherit from both Dog and Bird. Use virtual inheritance to avoid having two instances of the Animal class in FlyingDog:
class Animal
{
// Animal class members.
};
class Dog : virtual public Animal
{
// Dog class members.
};
class Bird : virtual public Animal
{
// Bird class members.
};
class FlyingDog : public Dog, public Bird
{
// FlyingDog class members.
};
The virtual keyword in the inheritance declaration ensures that only one instance of the Animal base class is shared by all of the classes in the hierarchy. It clears up any confusion that might have resulted from FlyingDog's Animal's various inheritance pathways.
Example:
Let's take a simple program to understand the use of virtual base class in C++.
#include <iostream>
class Animal
{
public:
int age;
Animal(int age) : age(age) {}
};
class Mammal : virtual public Animal
{
public:
Mammal(int age) : Animal(age) {}
};
class Bird : virtual public Animal
{
public:
Bird(int age) : Animal(age) {}
};
class Platypus : public Mammal, public Bird
{
public:
Platypus(int age) : Animal(age), Mammal(age), Bird(age) {}
};
int main()
{
Platypus platypus(5);
std::cout<< "Platypus age: " <<platypus.age<< std::endl;
return 0;
}
Output:
Platypus age: 5
Explanation:
In this example, Mammal and Bird both have Animal as their virtual base class. There is only one shared instance of Animal due to the Platypus class' virtual inheritance from Mammal and Bird. By doing so, redundant age member variables are avoided and the Platypus object has direct access to the age of the shared Animal instance.
Conclusion:
In conclusion, virtual functions enable polymorphism by allowing derived classes to override base class functions, while virtual base classes avoid ambiguity and guarantee appropriate shared inheritance when a class is inherited by different pathways in a class hierarchy.