design patterns · medium
Prototype Pattern
Prototype is a creational GoF pattern that creates new objects by cloning a prototypical, already-configured instance rather than by invoking a constructor or knowing the concrete class. Each type implements a virtual clone() — typically make_unique<T>(*this) — so a base pointer copies the correct derived type, making clone() effectively a 'virtual copy constructor'. It is commonly paired with a registry (a map from key to ready-made prototype objects): the client looks up a prototype and clones it to get a fresh, editable copy, never naming the concrete class. This turns object creation into data and lets you add or remove product types at runtime (from config or user actions) without changing the creation site — Prototype's advantage over factory patterns, which construct by type through subclassed factories. Use it when construction is expensive (heavy initialization), when you want to capture a runtime-tuned state as a reusable template, or when the client must stay decoupled from concrete types. Its main pitfalls are correctly deep-copying objects that own pointers or resources (a shallow copy silently aliases state) and cloning objects with circular references; every concrete class must also implement clone() correctly. Contrast with Builder, which assembles a complex object step by step, whereas Prototype duplicates one that already exists.
Prototype (creational): create new objects by CLONING a configured instance via a virtual clone() (make_unique<T>(*this)) instead of calling a constructor or knowing the concrete class — a 'virtual copy constructor'. Pair it with a map<key,prototype> registry to make creation runtime-extensible and data-driven; it skips expensive re-initialization. The trap is deep-vs-shallow copy. Factories build by type; Prototype duplicates an existing instance.
The code
// Prototype — create new objects by CLONING an existing instance,// not by calling a constructor / knowing the concrete class.struct Shape { virtual std::unique_ptr<Shape> clone() const = 0; // virtual ctor virtual void draw() const = 0; virtual ~Shape() = default;};
class Circle : public Shape { int r_; Color c_; // possibly expensive-to-configure statepublic: Circle(int r, Color c) : r_(r), c_(c) {} std::unique_ptr<Shape> clone() const override { return std::make_unique<Circle>(*this); // copy-construct SELF } void draw() const override { /* ... */ }};
// A registry of ready-made prototypes; clone to get a fresh, editable copy.std::unordered_map<std::string, std::unique_ptr<Shape>> registry;registry["red-circle"] = std::make_unique<Circle>(10, RED);
auto s = registry["red-circle"]->clone(); // new object, no ctor calls->draw(); // client never named CircleWhat this lesson walks through
- 01Intent — copy an existing object, don't build anew
- 02Structure — virtual clone() + a registry
- 03Stamp out copies from a configured original
- 04Gotcha — shallow clone shares owned resources
Prototype creates new objects by COPYING an existing, already-configured instance rather than constructing from scratch. Useful when construction is expensive, or when the exact class to build is decided at runtime.
See it animated — step by step, at your own pace
Unlock the full interactive walkthrough of Prototype Pattern and 100+ animated C++ interview lessons.