
- C++ Home
- C++ Overview
- C++ Environment Setup
- C++ Basic Syntax
- C++ Comments
- C++ Hello World
- C++ Omitting Namespace
- C++ Tokens
- C++ Constants/Literals
- C++ Keywords
- C++ Identifiers
- C++ Data Types
- C++ Numeric Data Types
- C++ Character Data Type
- C++ Boolean Data Type
- C++ Variable Types
- C++ Variable Scope
- C++ Multiple Variables
- C++ Input Output Operations
- C++ Basic Input/Output
- C++ Cin
- C++ Cout
- C++ Manipulators
- Type System & Data Representation
- C++ Modifier Types
- C++ Storage Classes
- C++ Constexpr Specifier
- C++ Numbers
- C++ Enumeration
- C++ Enum Class
- C++ References
- C++ Date & Time
- C++ Operators
- C++ Operators
- C++ Arithmetic Operators
- C++ Relational Operators
- C++ Logical Operators
- C++ Bitwise Operators
- C++ Assignment Operators
- C++ sizeof Operator
- C++ Conditional Operator
- C++ Comma Operator
- C++ Member Operators
- C++ Casting Operators
- C++ Pointer Operators
- C++ Operators Precedence
- C++ Unary Operators
- C++ Scope Resolution Operator
- C++ Control Statements
- C++ Decision Making
- C++ if Statement
- C++ if else Statement
- C++ Nested if Statements
- C++ switch Statement
- C++ Nested switch Statements
- C++ Loop Types
- C++ while Loop
- C++ for Loop
- C++ do while Loop
- C++ Foreach Loop
- C++ Nested Loops
- C++ Jump Statements
- C++ break Statement
- C++ continue Statement
- C++ goto Statement
- C++ Return Values
- C++ Strings
- C++ Strings
- C++ Loop Through a String
- C++ String Length
- C++ String Concatenation
- C++ String Comparison
- C++ Functions
- C++ Functions
- C++ Multiple Function Parameters
- C++ Recursive Function
- C++ Function Overloading
- C++ Function Overriding
- C++ Default Arguments
- C++ Arrays
- C++ Arrays
- C++ Multidimensional Arrays
- C++ Pointer to an Array
- C++ Passing Arrays to Functions
- C++ Return Array from Functions
- C++ Array Decay
- C++ Structure & Union
- C++ Structures
- C++ Unions
- C++ Class and Objects
- C++ Object Oriented
- C++ Classes & Objects
- C++ Class Member Functions
- C++ Class Access Modifiers
- C++ Static Class Members
- C++ Static Data Members
- C++ Static Member Function
- C++ Inline Functions
- C++ this Pointer
- C++ Friend Functions
- C++ Pointer to Classes
- C++ Constructors
- C++ Constructor & Destructor
- C++ Default Constructors
- C++ Parameterized Constructors
- C++ Copy Constructor
- C++ Constructor Overloading
- C++ Constructor with Default Arguments
- C++ Delegating Constructors
- C++ Constructor Initialization List
- C++ Dynamic Initialization Using Constructors
- C++ Destructors
- C++ Virtual Destructor
- C++ Inheritance
- C++ Inheritance
- C++ Multiple Inheritance
- C++ Multilevel Inheritance
- C++ Object-oriented
- C++ Overloading
- C++ Polymorphism
- C++ Abstraction
- C++ Encapsulation
- C++ Interfaces
- C++ Virtual Function
- C++ Pure Virtual Functions & Abstract Classes
- C++ Override Specifiers
- C++ Final Specifiers
- C++ Design Patterns
- C++ Creational Design Patterns
- C++ Singleton Design Pattern
- C++ Factory Method Design Pattern
- C++ Abstract Factory Pattern
- C++ Prototype Design Pattern
- C++ Structural Design Patterns
- C++ File Handling
- C++ Files and Streams
- C++ Reading From File
- C++ Advanced
- C++ Exception Handling
- C++ Dynamic Memory
- C++ Namespaces
- C++ Templates
- C++ Preprocessor
- C++ Signal Handling
- C++ Multithreading
- C++ Web Programming
- C++ Socket Programming
- C++ Concurrency
- C++ Advanced Concepts
- C++ Lambda Expression
- C++ nullptr
- C++ unordered_multiset
- C++ Structural Design Patterns
- C++ Adapter Pattern
- C++ Bridge Pattern
- C++ Composite Pattern
- C++ Decorator Pattern
Decorator Design Pattern in C++
A decorator is a Structural Design Pattern that allows us to add new functionalities to an existing object without changing or disturbing its structure. It lets us attach new behaviors to an object by placing that object inside another special wrapper object that contains the new behavior.
Let's understand in detail with an example. Imagine you have a simple text editor application with basic text features like writing and saving or editing text. Now, your manager wants you to add some new features like spell checking and grammar checking. If you are using the Decorator Design Pattern, you can easily add these new features without changing the existing code of the text editor. You can create separate decorator classes for spell checking and grammar checking that wrap around the original text editor class.

Components of Decorator Design Pattern
There are four main components of Decorator Design Pattern, as shown in the following image. Also, the client is the one who uses these components to perform operations. We have added two

Let's understand each of these components in detail −
- Component − This is an interface or abstract class that defines the common methods for both the concrete component and the decorators. In our example, this would be the interface for the text editor.
- Concrete Component − This is the class that implements the component interface and represents the original object that we want to add new functionalities to. In our example, this would be the basic text editor class.
- Decorator − This is an abstract class that also implements the component interface and has a reference to a component object. The decorator class is responsible for adding new functionalities to the component object. In our example, this would be the abstract decorator class for the text editor.
- Concrete Decorators − These are the classes that extend the decorator class and implement the new functionalities. In our example, these would be the spell checker and grammar checker classes that add their respective functionalities to the text editor.
Implementation of Decorator Design Pattern in C++
Earlier, we discussed the components of the Decorator Design Pattern. Now, let's see how we can implement it in C++.
In this implementation, we will create a simple Music Player application where we have a basic music player that can play music. We will then create decorators to add new functionalities like Shuffle and Repeat to the music player.

Steps to Implement Decorator Design Pattern
Let's see how we can implement the Decorator Design Pattern in C++
- Create a Component interface for the music player.
- Implement a Concrete Component class for the basic music player.
- Create an abstract Decorator class that implements the Component interface.
- Implement two concrete Decorator classes for shuffle and repeat functionalities.
- Create a Client class to use the music player with decorators.
C++ Code for Decorator Design Pattern
Let's look at the C++ code for the Decorator Design Pattern implementation of a Music Player application.
Here we will use all the components of the Decorator Design Pattern that we discussed earlier. We will create a Component interface for the music player, a Concrete Component class for the basic music player, an abstract Decorator class that implements the Component interface, and concrete Decorator classes for shuffle and repeat functionalities.
#include <iostream> using namespace std; // Component class MusicPlayer { public: virtual void play() = 0; virtual ~MusicPlayer() {} }; // Concrete Component class BasicMusicPlayer : public MusicPlayer { public: void play() { cout << "Playing music..." << endl; } }; // Decorator class MusicPlayerDecorator : public MusicPlayer { protected: MusicPlayer* player; public: MusicPlayerDecorator(MusicPlayer* p) : player(p) {} virtual void play() { player->play(); } virtual ~MusicPlayerDecorator() { delete player; } }; // Concrete Decorator for Shuffle class ShuffleDecorator : public MusicPlayerDecorator { public: ShuffleDecorator(MusicPlayer* p) : MusicPlayerDecorator(p) {} void play() { cout << "Shuffling playlist..." << endl; player->play(); } }; // Concrete Decorator for Repeat class RepeatDecorator : public MusicPlayerDecorator { public: RepeatDecorator(MusicPlayer* p) : MusicPlayerDecorator(p) {} void play() { cout << "Repeating current song..." << endl; player->play(); } }; // Client int main() { MusicPlayer* player = new BasicMusicPlayer(); MusicPlayer* shufflePlayer = new ShuffleDecorator(player); MusicPlayer* repeatShufflePlayer = new RepeatDecorator(shufflePlayer); cout << "Basic Music Player:" << endl; player->play(); cout << "\nMusic Player with Shuffle:" << endl; shufflePlayer->play(); cout << "\nMusic Player with Shuffle and Repeat:" << endl; repeatShufflePlayer->play(); delete repeatShufflePlayer; // This will also delete shufflePlayer and player return 0; }
Following is the output of the above code −
Basic Music Player: Playing music... Music Player with Shuffle: Shuffling playlist... Playing music... Music Player with Shuffle and Repeat: Repeating current song... Shuffling playlist... Playing music...
Pros and Cons of Decorator Design Pattern
The following table highlights the pros and cons of using the Decorator Design Pattern −
Pros | Cons |
---|---|
Allows adding new functionality without altering existing code. | Can lead to a large number of small classes. |
Promotes code reusability by using composition over inheritance. | Can make the code more complex and harder to understand. |
Stick to the Single Responsibility Principle by dividing functionalities into separate classes. | Debugging can be more difficult due to the multiple layers of wrapping. |
Enhances flexibility by allowing dynamic addition of responsibilities. | There could be performance overhead due to multiple layers of wrapping. |
Can be combined with other design patterns for more complex scenarios. | May lead to issues with object identity and equality checks. |
When to Use Decorator Design Pattern?
Following are some scenarios where you should consider using the Decorator Design Pattern −
- To add more functionalities to an object dynamically.
- When you want to avoid class explosion due to multiple combinations of features.
- To stick to the Single Responsibility Principle by dividing functionalities into separate classes.
- For adding responsibilities to individual objects without affecting other objects of the same class.
- To enhance the behavior of an object at runtime.
Real-world Applications of Decorator Design Pattern
The following image illustration some of real-world applications of Decorator Design Pattern -

Conclusion
In this chapter, we learned about the Decorator Design Pattern, its components, implementation steps, and a C++ code example. We also discussed the pros and cons of using this pattern, when to use it, and some real-world applications. The Decorator Design Pattern is a powerful tool that allows us to add new functionalities to existing objects without changing their structure, which in turn makes it easy for us to maintain and extend our program codes.