Back to C++
2026-04-065 min read

C++ Prototype Design Pattern

Learn C++ Prototype Design Pattern step by step with clear examples and exercises.

Title: C++ Prototype Design Pattern: A full guide for Object-Oriented Programming

Why This Matters

The Prototype Design Pattern is a crucial concept in object-oriented programming (OOP) for C++ developers. It allows you to create objects using an existing object as a prototype, which can significantly reduce memory usage and improve efficiency, especially when dealing with complex objects or objects that are expensive to create. This pattern is particularly useful when the creation of new objects involves lengthy initialization processes or heavy computations.

Prerequisites

Before diving into the Prototype Design Pattern, ensure you have a solid understanding of the following concepts:

  • Object-Oriented Programming (OOP) in C++
  • Classes and objects
  • Constructors and destructors
  • Copy constructors and assignment operators
  • Polymorphism
  • Understanding of dynamic memory allocation using new and delete operators
  • Familiarity with the Factory Design Pattern

Core Concept

The Prototype Design Pattern is a creational design pattern that allows you to create new objects by copying an existing object, known as the prototype. This pattern can be particularly useful when dealing with complex objects or objects whose creation involves expensive operations.

To implement the Prototype Design Pattern in C++, we need three main components:

  1. An abstract prototype class that serves as a template for creating concrete prototypes and contains a pure virtual clone() method.
  2. Concrete prototype classes, which are instances of the abstract prototype class that implement the clone() method to create new objects of their own type.
  3. A factory or client that uses the clone() method to create new objects.

In this guide, we will focus on understanding these components and providing examples for their implementation.

Abstract Prototype

An abstract prototype is a base class that serves as a template for creating concrete prototypes. It typically includes a pure virtual clone() method that must be implemented by the concrete prototype.

class Prototype {
public:
virtual Prototype* clone() const = 0;
};

Concrete Prototype

A concrete prototype is an instance of a class derived from the abstract prototype. It implements the clone() method to create a new object of its own type.

class ConcretePrototype : public Prototype {
public:
// Implementation of clone() method
};

Factory or Client

The factory or client is responsible for creating new objects using the clone() method. It typically takes an existing object and returns a copy of it.

Prototype* createPrototype(const Prototype& prototype) {
return prototype.clone();
}

Worked Example

Let's consider a simple example where we have a Shape class that serves as an abstract prototype, and Circle and Rectangle classes as concrete prototypes. The Shape class has a method to calculate the area of the shape, while the concrete prototypes implement their own area calculation methods.

#include <iostream>
using namespace std;

class Prototype {
public:
virtual double area() const = 0;
virtual Prototype* clone() const = 0;
};

class Circle : public Prototype {
private:
double radius;

public:
Circle(double radius) : radius(radius) {}

double area() const override {
return 3.14 * radius * radius;
}

Prototype* clone() const override {
return new Circle(*this);
}
};

class Rectangle : public Prototype {
private:
int width, height;

public:
Rectangle(int width, int height) : width(width), height(height) {}

double area() const override {
return width * height;
}

Prototype* clone() const override {
return new Rectangle(*this);
}
};

void printArea(Prototype& prototype) {
cout << "Area: " << prototype.area() << endl;
Prototype* cloned = prototype.clone();
cout << "Cloned object area: " << cloned->area() << endl;
}

int main() {
Circle circle(5);
Rectangle rectangle(4, 6);

printArea(circle);
printArea(rectangle);

return 0;
}

In this example, we have a Prototype class that serves as an abstract prototype. The Circle and Rectangle classes are concrete prototypes, each implementing the clone() method to create a new object of its own type. The printArea() function demonstrates how to use these objects and their clones.

Common Mistakes

  1. ### Forgetting to make the clone() method pure virtual in the abstract prototype class

This will prevent derived classes from implementing the clone() method, making it impossible to create new objects using the Prototype Design Pattern.

  1. ### Not properly handling polymorphism when cloning objects

If the concrete prototypes are not correctly implemented to handle polymorphism, you may encounter runtime errors or incorrect behavior when working with multiple object types.

  1. ### Neglecting to deep-clone complex objects

When dealing with complex objects that contain pointers or references to other objects, it's essential to perform a deep copy instead of a shallow one to avoid unexpected side effects and memory leaks.

  1. ### Not releasing the memory allocated by the prototype object after cloning

After creating a new object using the clone() method, it's important to release the memory occupied by the original prototype object to prevent memory leaks.

Subheadings under Common Mistakes:

  • Forgetting to release the memory of the prototype object
  • Failing to handle polymorphism correctly
  • Neglecting deep-copying of complex objects
  • Not releasing the memory of the prototype object after cloning

Practice Questions

  1. Implement the Prototype Design Pattern for a Stack class in C++. The Stack should have a maximum size and use dynamic memory allocation.
  2. Modify the example provided to handle deep-copying of objects containing pointers or references to other objects.
  3. Create a Factory class that uses the Prototype Design Pattern to create different types of Shapes (Circle, Rectangle, Triangle) based on user input.
  4. Implement a clone() method for a complex object that contains a dynamically allocated array and ensures deep-copying of the array's contents.
  5. Modify the example provided to handle exceptions during the cloning process and properly release the memory occupied by the prototype object in case of an exception.
  6. ### Bonus Question:

Incorporate the Prototype Design Pattern into a more complex project, such as a simple text editor that allows users to save and reload their documents.

FAQ

The Prototype Design Pattern offers more flexibility than copy constructors and assignment operators, especially when dealing with complex objects or objects that cannot be easily copied. It allows for the creation of new objects using an existing object as a template, reducing memory usage and improving efficiency.

### Can I use the Prototype Design Pattern with classes that have private constructors?

Yes, you can use the Prototype Design Pattern with classes that have private constructors by making the constructor protected or providing a public factory method that creates objects using the clone() method.

### Is it necessary to implement the Prototype Design Pattern for every class that has an expensive initialization process?

Not necessarily. The Prototype Design Pattern should be used when creating new objects is expensive, and you want to reduce memory usage or improve efficiency. If the initialization process of a particular class is not expensive, there may be no need to implement the Prototype Design Pattern.

### How does the Prototype Design Pattern compare to the Singleton Design Pattern?

The Prototype Design Pattern focuses on creating multiple objects using an existing object as a template, while the Singleton Design Pattern ensures that only one instance of a class exists at any given time. Although both patterns aim to improve efficiency, they serve different purposes and are not mutually exclusive.

C++ Prototype Design Pattern | C++ | XQA Learn