0
0
CppComparisonBeginner · 4 min read

Virtual Function vs Pure Virtual Function in C++: Key Differences

A virtual function in C++ provides a default implementation that derived classes can override, enabling runtime polymorphism. A pure virtual function has no implementation in the base class and forces derived classes to provide their own version, making the base class abstract.
⚖️

Quick Comparison

This table summarizes the main differences between virtual functions and pure virtual functions in C++.

AspectVirtual FunctionPure Virtual Function
DefinitionFunction with default implementation in base classFunction with no implementation, declared with = 0
PurposeAllows overriding but provides base behaviorForces derived classes to implement the function
Base Class InstantiationBase class can be instantiatedBase class becomes abstract and cannot be instantiated
Syntaxvirtual void func();virtual void func() = 0;
Use CaseOptional override, common behavior sharedDefines interface, enforces implementation
PolymorphismSupports runtime polymorphismSupports runtime polymorphism and abstraction
⚖️

Key Differences

A virtual function in C++ is a member function declared with the virtual keyword that provides a default behavior in the base class. Derived classes can override it to change or extend this behavior, but if they don't, the base class version is used. This allows flexible polymorphism where the base class can be used directly or extended.

In contrast, a pure virtual function is declared by assigning = 0 in its declaration, indicating it has no implementation in the base class. This makes the base class abstract, meaning you cannot create objects of it directly. Derived classes must override and provide their own implementation of this function to be instantiable.

Thus, virtual functions provide optional overriding with a default, while pure virtual functions enforce overriding and define an interface or contract for derived classes. This distinction is key for designing class hierarchies that use polymorphism effectively.

⚖️

Code Comparison

Here is an example using a virtual function to show how derived classes can override a base class method but the base class can still be instantiated.

cpp
#include <iostream>
using namespace std;

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

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

int main() {
    Animal a;
    Dog d;

    a.sound();  // Calls base class version
    d.sound();  // Calls derived class override

    Animal* ptr = &d;
    ptr->sound(); // Calls derived class version due to virtual

    return 0;
}
Output
Animal makes a sound Dog barks Dog barks
↔️

Pure Virtual Function Equivalent

This example shows a pure virtual function making the base class abstract. You cannot create an Animal object directly, and derived classes must implement sound().

cpp
#include <iostream>
using namespace std;

class Animal {
public:
    virtual void sound() = 0; // Pure virtual function
};

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

int main() {
    // Animal a; // Error: cannot instantiate abstract class
    Dog d;
    d.sound();  // Calls derived class implementation

    Animal* ptr = &d;
    ptr->sound(); // Calls derived class version

    return 0;
}
Output
Dog barks Dog barks
🎯

When to Use Which

Choose a virtual function when you want to provide a default behavior in the base class but allow derived classes to override it optionally. This is useful when the base class can stand on its own and you want to share common code.

Choose a pure virtual function when you want to define an interface or contract that all derived classes must follow, making the base class abstract. This enforces that derived classes provide their own specific implementation and prevents creating incomplete base objects.

In summary, use virtual functions for optional overriding with default behavior, and pure virtual functions to create abstract base classes that define required methods.

Key Takeaways

Virtual functions provide default behavior and allow optional overriding.
Pure virtual functions have no base implementation and force derived classes to implement them.
Pure virtual functions make the base class abstract and non-instantiable.
Use virtual functions for shared behavior; use pure virtual functions to define interfaces.
Polymorphism works with both, but pure virtual functions enforce design contracts.