ReviseAlgo Logo

Design Patterns in C++

Factory Pattern

Decouple object creation from client code using Factory Method patterns and smart pointers.

Interview: Polymorphism, using std::unique_ptr for return types, and enforcing the Open-Closed Principle.

Last Updated: June 13, 2026 9 min read

The Factory Pattern delegates object creation to specialized classes. This keeps your code modular and decoupled, allowing you to introduce new types without modifying client code.

Decoupling

Client code interacts only with abstract base interfaces, remaining decoupled from concrete subclasses.

std::unique_ptr

Always return resource-managed pointers (like std::unique_ptr) from factory methods to prevent memory leaks.

Open-Closed

Enforces the Open-Closed Principle: you can add new product classes without changing existing factory structures.

Smart Pointer Returns

In legacy C++, factory methods returned raw pointers, transferring ownership to the caller. This often led to memory leaks if the caller forgot to delete the object.

Modern C++ resolving this by returning std::unique_ptr. This defines clear ownership rules and guarantees clean resource management.

Code Walkthrough

A polymorphic UI button creation factory using modern smart pointers.

Interview-Relevant Information

Q: Why should a factory method return std::unique_ptr instead of std::shared_ptr?
Answer: Returning a std::unique_ptr is the most flexible approach. It allows the caller to manage the object's lifetime individually. If shared ownership is required later, the caller can convert the std::unique_ptr to a std::shared_ptr using std::move.

Q: How does the Factory pattern support the Open-Closed Principle?
Answer: It allows you to introduce new product subclasses to the system without modifying existing client code. Client code interacts only with the abstract base interface, remaining decoupled from concrete subclasses.

Quick Checklist

Did you define a virtual destructor in the base class? Are factory methods returning smart pointers? If yes, your Factory implementation is robust.

Use Cases

Instantiating dynamic game characters or AI agents based on configuration profiles.

Constructing polymorphic database or network adapters dynamically at runtime.

Common Mistakes

Forgetting to declare a virtual destructor in the base class, leading to memory leaks when deleting objects.

Returning raw pointers, shifting the responsibility of manual memory management back to the caller.