Adapter Design Pattern in C++ | Master CPP Design Patterns 2025

Introduction of Adapter Design Pattern

Adapter Design Pattern : When working on large software systems, you may come across situations where two incompatible interfaces need to work together. Instead of modifying existing code (which may be risky or impossible), you can use the Adapter Pattern to make them compatible.

The Adapter Pattern acts like a bridge between two interfaces. It’s part of the Structural Design Patterns family in C++.

What is the Adapter Design Pattern?

The Adapter Design Pattern allows incompatible interfaces to work together by wrapping an existing class with a new interface.

In simple terms, it’s like using a power plug adapter that lets a U.S. plug fit into a European socket.

Real-life Analogy

Imagine you have an old VGA cable that only works with projectors, but your laptop only has an HDMI port. You can’t plug it in directly. So, you use an HDMI-to-VGA adapter. Now your laptop can talk to the projector!

That’s exactly what the Adapter Pattern does in code.

Components of the Adapter Pattern

  1. Target – The expected interface (what your code is designed to use)
  2. Adaptee – The existing class that needs adapting
  3. Adapter – The class that wraps the Adaptee and makes it compatible with Target

When to Use the Adapter Pattern

  • When you want to reuse an existing class, but its interface doesn’t match what you need.
  • When you want to decouple code from third-party libraries or legacy code.
  • When integrating new features into old systems.

Adapter Pattern in C++ – Code Example

Let’s look at a simple C++ example to understand how it works.

Problem:

We have an existing OldPrinter class. But our system expects printers to use the NewPrinterInterface.

Step 1: Define the Target Interface

// Target Interface
class NewPrinterInterface {
public:
    virtual void printDocument(const std::string& text) = 0;
    virtual ~NewPrinterInterface() {}
};

Step 2: Existing Class (Adaptee)

// Adaptee
class OldPrinter {
public:
    void oldPrint(const std::string& text) {
        std::cout << "Old Printer Output: " << text << std::endl;
    }
};

Step 3: Create the Adapter

// Adapter
class PrinterAdapter : public NewPrinterInterface {
private:
    OldPrinter* oldPrinter;

public:
    PrinterAdapter(OldPrinter* printer) : oldPrinter(printer) {}

    void printDocument(const std::string& text) override {
        // Convert the request to match the old interface
        oldPrinter->oldPrint(text);
    }
};

Step 4: Client Code

int main() {
    OldPrinter* legacyPrinter = new OldPrinter();

    // Use adapter to make it compatible with the new interface
    NewPrinterInterface* printer = new PrinterAdapter(legacyPrinter);

    printer->printDocument("Hello, Adapter Pattern!");

    delete printer;
    delete legacyPrinter;

    return 0;
}

Output

Old Printer Output: Hello, Adapter Pattern!

Success! The OldPrinter works with the new system using the adapter.

Types of Adapters

  • Class Adapter (using inheritance): Inherit from both Target and Adaptee (only works in languages with multiple inheritance like C++).
  • Object Adapter (using composition): Use a reference to Adaptee inside the Adapter. This is more flexible and used in our example above.

Benefits of Adapter Pattern

  • Promotes reusability of existing classes
  • Helps in code migration and integration
  • Makes your design more flexible and maintainable

Drawbacks

  • Adds extra layers of code
  • May lead to performance overhead
  • Can make debugging slightly harder due to indirection

Adapter vs. Other Patterns

PatternPurpose
AdapterMakes incompatible interfaces compatible
DecoratorAdds behavior to an object dynamically
BridgeDecouples abstraction from implementation
FacadeProvides a simplified interface

Conclusion

The Adapter Pattern is a powerful tool in a C++ developer’s design toolbox. It allows your code to stay clean, extensible, and compatible with legacy or third-party systems. By wrapping old interfaces with new ones, you avoid rewriting or duplicating code.

Use it wisely when integrating different systems — and you’ll be building robust and scalable software like a pro!

FAQs – Adapter Pattern in C++

Q1. Is Adapter Pattern a structural design pattern?
Yes, it’s part of the Structural design patterns.

Q2. Can we implement Adapter without inheritance?
Yes! You can use composition (object adapter) for a more flexible solution.

Q3. Is Adapter Pattern the same as a Wrapper?
They are similar. A wrapper is a broader term; an adapter is a type of wrapper that converts interfaces.

You can also Visit other tutorials of Embedded Prep 

Special thanks to @mr-raj for contributing to this article on Embedded Prep

Leave a Reply

Your email address will not be published. Required fields are marked *