Virtual Vs Pure virtual function in CPP

Introduction

Welcome to the world of C++ programming, where we’ll unravel two important concepts: Virtual and Pure Virtual functions. Imagine them as tools to build super-flexible and strong programs. In this article, we’ll chat about why we even need them and how we can use them cleverly to create cool blueprints for classes. Think of these functions as magical ways to make your code more versatile. By the time we’re done, you’ll see how these functions add spice to your code, making it easier to change and grow. So, let’s dive in and make coding even more exciting!

What are Virtual Functions?

Virtual Functions: What Are They?

Imagine you have a team of superheroes in a computer program. Each superhero has a special power, like flying, super strength, or invisibility. Now, let’s say you want to organize a training session for your superheroes, but each one needs to practice their power differently. This is where virtual functions come in handy.

In programming, a virtual function is a concept that helps us manage different actions or behaviors for objects of the same class, just like our superheroes with different powers. It’s like giving each superhero their own customized training routine. Virtual functions are commonly used in object-oriented programming, where you define a base class with some functions, and then derived classes can customize those functions based on their specific needs.

Syntax and Simple Code Example:

C++
#include <iostream>

class Superhero {
public:
    virtual void usePower() {
        std::cout << "Generic power used" << std::endl;
    }
};

class FlyingHero : public Superhero {
public:
    void usePower() override {
        std::cout << "Flying power activated" << std::endl;
    }
};

class StrongHero : public Superhero {
public:
    void usePower() override {
        std::cout << "Super strength activated" << std::endl;
    }
};

int main() {
    Superhero* hero1 = new FlyingHero();
    Superhero* hero2 = new StrongHero();

    hero1->usePower();  // Output: Flying power activated
    hero2->usePower();  // Output: Super strength activated

    delete hero1;
    delete hero2;

    return 0;
}

Output:

C++
Flying power activated
Super strength activated

Explanation:

  • We start by creating a base class Superhero with a virtual function usePower().
  • Then, we create two derived classes, FlyingHero and StrongHero, both inheriting from Superhero.
  • In each derived class, we override the usePower() function to provide custom behavior for that specific hero type.
  • In the main() function, we create instances of both ‘FlyingHero‘ and ‘StrongHero‘ and assign them to pointers of type ‘Superhero‘.
  • When we call the ‘usePower()‘ function using these pointers, the correct version of the function is invoked based on the actual object’s type (polymorphism).
  • Finally, we clean up the dynamically allocated objects using ‘delete‘ to prevent memory leaks.

What are Pure Virtual Functions?

Pure Virtual Functions in Simple Terms:

Imagine you’re building a blueprint for different types of vehicles like cars, bikes, and trucks. You know that all vehicles have certain common features like “start,” “stop,” and “honk.” However, the specific way each type of vehicle performs these actions can be different. For instance, a car starts with a key, a bike with a kick, and a truck with a button.

In programming, we can create a similar concept using “classes” and “functions.” A class is like a blueprint, and functions are the actions that the objects based on that blueprint can perform. A pure virtual function is like a placeholder for an action that must be defined by any class that uses the blueprint. It’s a way of saying, “Hey, any object based on this blueprint must have this function, but I won’t provide the details here.”

Syntax with Simple Code Example:

C++
#include <iostream>

// Blueprint (abstract class)
class Vehicle {
public:
    virtual void start() = 0;  // Pure virtual function
    virtual void stop() = 0;   // Another pure virtual function
};

// Car class that follows the blueprint
class Car : public Vehicle {
public:
    void start() override {
        std::cout << "Car started with a key." << std::endl;
    }

    void stop() override {
        std::cout << "Car stopped." << std::endl;
    }
};

int main() {
    Car myCar;
    myCar.start();
    myCar.stop();

    return 0;
}

Output:

C++
Car started with a key.
Car stopped.

Explanation:

  • Pure virtual functions are used in C++ to create abstract classes, which are like blueprints for other classes.
  • A pure virtual function is declared using the syntax: virtual returnType functionName() = 0;.
  • You cannot create objects of an abstract class because it has an incomplete function.
  • Derived classes that inherit from an abstract class must provide definitions for all pure virtual functions.
  • In the example code, Vehicle is an abstract class with two pure virtual functions: start and stop.
  • The Car class inherits from Vehicle and provides specific implementations for the pure virtual functions.
  • In the main function, an object of the Car class is created and its start and stop functions are called.

Differences between virtual and pure virtual functions in C++:

AspectVirtual FunctionsPure Virtual Functions
DefinitionVirtual functions have a default implementation in the base class, but can be overridden by derived classes.Pure virtual functions have no implementation in the base class and must be overridden by derived classes.
Syntaxvirtual returnType functionName() {...}Virtual functions have a default implementation in the base class but can be overridden by derived classes.
UsageUsed in both base and derived classes.Used only in abstract base classes to create a blueprint for derived classes.
Object CreationObjects of the base class can be created.Cannot create objects of the abstract class that contains pure virtual functions.
Derived ImplementationDerived classes can choose to override the virtual function or use the base class implementation.Derived classes must override all pure virtual functions; otherwise, they remain abstract.
CompletenessA class with virtual functions can be instantiated on its own.An abstract class with pure virtual functions cannot be instantiated on its own.
Function CallingCalls to virtual functions are resolved at runtime based on the actual object type.Pure virtual functions are resolved at runtime like virtual functions, but the derived class’s implementation is called.
Function OverloadingCan be overloaded with different parameter lists.Can be overloaded with different parameter lists in the same way as virtual functions.
Default Implementation in Base ClassVirtual functions can provide a default behavior in the base class that can be optionally overridden.Pure virtual functions cannot have any implementation in the base class.
Forcing OverrideDerived classes can choose to override or not.Derived classes must provide an implementation for all pure virtual functions.
Differences between virtual and pure virtual functions in C++:

Examples of Virtual and Pure Virtual Functions in C++

Let’s look at some examples to see how virtual and pure virtual functions can be used in C++. We’ll provide the code, the expected output, and a step-by-step explanation of how virtual and pure virtual functions are used.

Example 1: Virtual Function

C++
#include<iostream>
using namespace std;

class Animal {
public:
    virtual void makeSound() {
        cout << "The animal makes a sound" << endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        cout << "The dog barks" << endl;
    }
};

int main() {
    Animal* animal = new Dog();

    animal->makeSound();

    delete animal;

    return 0;
}

Output:

C++
The dog barks

Explanation:

  • The code defines a base class Animal with a virtual function makeSound() that outputs a generic animal sound.
  • The Dog class inherits from Animal and overrides the makeSound() function to output “The dog barks”.
  • A pointer of type Animal is created and assigned a dynamically allocated Dog object.
  • The makeSound() function is called on the pointer, invoking the overridden function in Dog to output “The dog barks”.
  • The dynamically allocated object is deleted to free the memory.

Example 2: Pure Virtual Function

C++
#include<iostream>
using namespace std;

class Shape {
public:
    virtual void draw() = 0; // Pure virtual function
};

class Circle : public Shape {
public:
    void draw() override {
        cout << "Drawing a circle" << endl;
    }
};

int main() {
    Shape* shape = new Circle();

    shape->draw();

    delete shape;

    return 0;
}

Output:

C++
Drawing a circle

Explanation:

  • The code defines an abstract base class Shape with a pure virtual function draw().
  • The Circle class inherits from Shape and overrides the draw() function to draw a circle.
  • A pointer of type Shape is created and assigned a dynamically allocated Circle object.
  • The draw() function is called on the pointer, invoking the overridden function in Circle to draw a circle.
  • The dynamically allocated object is deleted to free the memory.

Advantages and Disadvantages of virtual and pure virtual functions:

AspectVirtual FunctionsPure Virtual Functions
Advantages– Provides a default implementation that can be used by derived classes.
– Offers flexibility for derived classes to override the function if needed.
– Allows object creation of the base class.
– Ensures derived classes implement a specific function.
– Defines a clear contract for derived classes to follow.
– Enables runtime polymorphism.
Disadvantages– Can lead to unintended behavior if not properly overridden in derived classes.
– Changes in base class implementation can impact multiple derived classes.
– Allows object creation of the base class.
– Requires derived classes to provide an implementation, reducing flexibility.
– Cannot create objects of the base class with pure virtual functions.
– Increases complexity due to mandatory function overrides.
Advantages and Disadvantages of virtual and pure virtual functions:

Key Takeaways

  • Blueprint for Flexibility: Virtual functions allow you to create a blueprint in a base class that can be customized by derived classes. This enables you to define a common interface while accommodating different implementations.
  • Runtime Polymorphism: Virtual functions enable polymorphism, where you can call a function on a base class pointer or reference, and the appropriate derived class function will be executed at runtime.
  • Pure Virtual Functions: By making a function pure virtual using the = 0 syntax, you create a placeholder that must be implemented by any derived class. This enforces consistency in derived classes’ behavior.
  • Abstract Classes: When a class contains pure virtual functions, it becomes an abstract class, meaning you can’t create objects of that class. Abstract classes are used as base blueprints for other classes.
  • Extensibility: Using virtual and pure virtual functions, you can build systems that are easily extendable. You can add new derived classes with unique behaviors without needing to modify existing code, promoting a modular and maintainable design.

Conclusion

In conclusion, virtual and pure virtual functions are like the recipe of a chef in C++. By understanding how to use virtual and pure virtual functions, you can write better, more flexible programs. So keep practicing, and soon you’ll be a pro at using virtual and pure virtual functions!

FAQs

  • What are virtual and pure virtual functions in C++?
    Virtual functions are member functions in the base class that you can override in a derived class. Pure virtual functions are functions in an abstract class that don’t have an implementation in the base class.
  • Why do we use virtual and pure virtual functions in C++?
    We use virtual and pure virtual functions in C++ to provide a structure for other functions. They ensure that every derived class provides certain functionalities.
  • How do we use virtual and pure virtual functions in C++?
    We use virtual functions by declaring them in the base class and overriding them in the derived class. We use pure virtual functions by declaring them in the abstract class with ‘= 0’ at the end. Derived classes must then provide the implementation for these functions.
  • Can using virtual and pure virtual functions make code more confusing?
    Yes, if you use virtual and pure virtual functions incorrectly, it can make your code more complex and harder to read. It’s important to understand when and how to use virtual and pure virtual functions effectively.
  • What are some examples of using virtual and pure virtual functions in C++?
    Some examples include using virtual functions to make different types of animal objects make different sounds, or using pure virtual functions to draw different types of shape objects differently.
Deepak Vishwakarma

Founder

RELATED Articles

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.