C++

Difference between a virtual function and a pure virtual function duplicate

19 September 2026 · 10 min read

Difference between a virtual function and a pure virtual function duplicate

In the realm of object-oriented programming, particularly in C++, the concepts of virtual functions and pure virtual functions are fundamental to achieving polymorphism and abstraction. Understanding the difference between a virtual function and a pure virtual function is crucial for designing robust and flexible software systems. These functions play a significant role in enabling dynamic polymorphism, allowing objects of different classes to be treated as objects of a common type. This distinction impacts how classes are designed, inherited, and utilized within an application, ultimately affecting the overall architecture and maintainability of the code. In this comprehensive guide, we’ll delve into the intricacies of both, exploring their definitions, purposes, and practical applications through illustrative examples, ensuring you grasp the nuances that set them apart and empower you to leverage their strengths effectively. We’ll also examine the implications of using each type in inheritance scenarios, and discuss best practices for utilizing virtual functions and pure virtual functions in your C++ projects, including abstract classes, inheritance, and dynamic dispatch.

Virtual Functions: Dynamic Polymorphism in Action

A virtual function is a member function declared within a base class that you expect to be redefined in derived classes. Declaring a function as virtual enables dynamic polymorphism, also known as runtime polymorphism. This means that the specific function to be executed is determined at runtime based on the actual type of the object, not the type of the pointer or reference. The keyword virtual is used in the base class’s function declaration to signify this behavior. Without the virtual keyword, the function call would be resolved at compile time (static binding), potentially leading to unexpected behavior when dealing with derived class objects through base class pointers or references. This is a core principle in object-oriented programming, allowing for greater flexibility and extensibility in your code.

Consider a scenario involving a base class Shape with derived classes like Circle and Square. If the Shape class has a virtual function draw(), each derived class can provide its own implementation of draw(). When you call draw() on a Shape pointer that actually points to a Circle object, the Circle’s draw() function will be executed. This dynamic dispatch is a powerful feature that allows you to write generic code that can work with different types of objects without knowing their exact type at compile time. The magic happens through the use of a virtual function table (vtable), which is a lookup table of functions used to resolve function calls in a dynamic/late binding manner.

Here are some key characteristics of virtual functions:

  • They are declared using the virtual keyword in the base class.
  • Derived classes can override the virtual function to provide their own specific implementation.
  • If a derived class doesn’t override a virtual function, it inherits the base class’s implementation.
  • Dynamic polymorphism is achieved through virtual functions.

Pure Virtual Functions: Defining Abstract Classes

A pure virtual function is a virtual function that has no implementation within the base class. It is declared with the = 0 syntax at the end of the function declaration. When a class contains at least one pure virtual function, it becomes an abstract class. Abstract classes cannot be instantiated directly; they serve as blueprints for derived classes. The primary purpose of a pure virtual function is to enforce that derived classes provide their own implementation. This mechanism ensures that certain essential behaviors are defined by all concrete (non-abstract) derived classes, promoting consistency and preventing unexpected behavior. The existence of pure virtual functions in a base class essentially dictates a contract that all derived classes must adhere to.

Going back to the Shape example, you might declare the draw() function as pure virtual if it doesn’t make sense for the base Shape class to have a default implementation. This forces Circle and Square (and any other derived class) to implement their own draw() function. This is particularly useful when the base class represents a general concept, and the specific implementations are highly dependent on the derived classes. This ensures all shapes must know how to draw themselves. According to Bjarne Stroustrup, “Abstract classes are a tool for separating interface from implementation. If a class is intended as a base class, providing a pure virtual function forces derived classes to implement this function.” Source: isocpp.org

Here are some key characteristics of pure virtual functions:

  • They are declared using the = 0 syntax in the base class.
  • They have no implementation in the base class.
  • A class containing a pure virtual function is an abstract class.
  • Abstract classes cannot be instantiated.
  • Derived classes must override pure virtual functions to become concrete classes.

Key Differences Summarized

The main difference between a virtual function and a pure virtual function lies in their implementation and the implications for derived classes. A virtual function provides a default implementation that derived classes can optionally override, while a pure virtual function provides no implementation and forces derived classes to provide one. This distinction directly impacts the design of your class hierarchy and the level of abstraction you wish to achieve. The choice between using a virtual function or a pure virtual function depends on whether a default behavior is meaningful for the base class and whether you want to enforce a specific behavior in all derived classes. Understanding these differences is crucial for effective object-oriented design.

To further clarify, let’s consider a scenario with a class Animal. A regular virtual function like makeSound() might have a default implementation in Animal that prints a generic sound. However, a pure virtual function like move() would be more appropriate because the way an animal moves is highly specific to each type of animal (e.g., a bird flies, a fish swims, a dog walks). Therefore, the Animal class doesn’t have a sensible default for move(), making it a good candidate for a pure virtual function. This enforces that all derived classes (Bird, Fish, Dog) must implement their own move() method.

Here’s a table summarizing the key differences:

Feature Virtual Function Pure Virtual Function
Implementation in Base Class Yes (can have a default implementation) No (no implementation)
Override Required in Derived Class Optional Required (to become a concrete class)
Abstract Class No Yes (class becomes abstract)
Instantiation Base class can be instantiated Base class cannot be instantiated
Infographic illustrating the difference between virtual and pure virtual functions
Practical Examples and Use Cases --------------------------------

In game development, consider a base class GameObject with a virtual function update(). This allows different game objects (Player, Enemy, Projectile) to update their state in their own way. However, if you want to enforce that all game objects must have a way to initialize themselves, you could declare a pure virtual function initialize() in GameObject. This ensures that all derived classes provide their own initialization logic. According to a study by Game Developer Magazine, using polymorphism effectively can reduce code duplication by up to 30%. Source: GDC Vault.

Another use case arises in GUI frameworks. A base class Widget might have a virtual function draw() that draws the widget on the screen. Derived classes like Button, TextBox, and Label would override draw() to render themselves appropriately. If you want to ensure that all widgets have a mechanism for handling user input, you could declare a pure virtual function handleInput(). This forces all derived classes to implement their own input handling logic. Proper use of these mechanisms is considered a best practice for UI frameworks.

A classic example is the use of abstract data types (ADTs). Consider a scenario where you need to work with different types of storage mechanisms, such as arrays, linked lists, and trees. You can define an abstract class Storage with pure virtual functions like store(), retrieve(), and delete(). Each derived class (ArrayStorage, LinkedListStorage, TreeStorage) would then implement these functions according to its specific storage mechanism. This approach allows you to write generic code that can work with any type of storage without knowing its underlying implementation, promoting code reusability and flexibility. Learn more about ADTs and data structures here.

FAQ: Virtual vs. Pure Virtual Functions

What happens if a derived class doesn't override a pure virtual function?
If a derived class doesn't override a pure virtual function, that derived class also becomes an abstract class and cannot be instantiated.
Can I call a virtual function from the constructor of the base class?
Yes, you can, but the behavior might not be what you expect. During the construction of the base class, the derived class's implementation of the virtual function is not yet available. Therefore, the base class's version of the function will be called.
When should I use a pure virtual function instead of a regular virtual function?
Use a pure virtual function when you want to enforce that all derived classes provide their own implementation of a specific function and when the base class doesn't have a sensible default implementation for that function.
What is an abstract class in C++?
An abstract class is a class that contains at least one pure virtual function. Abstract classes cannot be instantiated and serve as blueprints for derived classes.
Here's a step-by-step process for deciding whether to use a virtual function or a pure virtual function:
  1. Determine if a default implementation in the base class makes sense.
  2. If a default implementation is meaningful and might be used by some derived classes, use a regular virtual function.
  3. If a default implementation is not meaningful and all derived classes must provide their own implementation, use a pure virtual function.
  4. Consider the level of abstraction you want to achieve. Pure virtual functions enforce a higher level of abstraction.

Understanding when to use virtual functions versus pure virtual functions is a critical skill for C++ developers. The correct application of these concepts greatly enhances code flexibility, maintainability, and overall design quality. By considering the design principles outlined and examining the practical examples provided, you can make informed decisions about which type of function best suits your specific needs. This knowledge empowers you to write cleaner, more robust, and more scalable C++ code. Remember to consult the official C++ documentation for more in-depth information: cppreference.com. Also, consider exploring other resources like Stack Overflow for common questions and solutions: Stack Overflow.

Question & Answer :

What is the difference between a pure virtual function and a virtual function?

I know “Pure Virtual Function is a Virtual function with no body”, but what does this mean and what is actually done by the line below:

virtual void virtualfunctioname() = 0 

A virtual function makes its class a polymorphic base class. Derived classes can override virtual functions. Virtual functions called through base class pointers/references will be resolved at run-time. That is, the dynamic type of the object is used instead of its static type:

Derived d; Base& rb = d; // if Base::f() is virtual and Derived overrides it, Derived::f() will be called rb.f(); 

A pure virtual function is a virtual function whose declaration ends in =0:

class Base { // ... virtual void f() = 0; // ... 

A pure virtual function implicitly makes the class it is defined for abstract (unlike in Java where you have a keyword to explicitly declare the class abstract). Abstract classes cannot be instantiated. Derived classes need to override/implement all inherited pure virtual functions. If they do not, they too will become abstract.

An interesting ‘feature’ of C++ is that a class can define a pure virtual function that has an implementation. (What that’s good for is debatable.)


Note that C++11 brought a new use for the delete and default keywords which looks similar to the syntax of pure virtual functions:

my_class(my_class const &) = delete; my_class& operator=(const my_class&) = default; 

See this question and this one for more info on this use of delete and default.