C++ Composite Pattern Example

In this article, we will learn how to use and implement the Composite Pattern in C++ with an example.

Composite is a structural design pattern that lets you compose objects into tree structures and then work with these structures as if they were individual objects.

C++ Composite Pattern Example

The below diagram shows the generic structure of the Composite Pattern:
Let's refer to the above structure to create an example to demonstrates the usage of the Composite Pattern.
#include <iostream>
#include <vector>

/*
 * Component
 * defines an interface for all objects in the composition
 * both the composite and the leaf nodes
 */
class Component
{
public:
    virtual ~Component() {}

    virtual Component *getChild( int )
    {
        return 0;
    }

    virtual void add( Component * ) {
        /* ... */
    }
    virtual void remove( int ) {
        /* ... */
    }

    virtual void operation() = 0;
};

/*
 * Composite
 * defines behavior of the components having children
 * and store child components
 */
class Composite : public Component
{
public:
    ~Composite()
    {
        for ( unsigned int i = 0; i < children.size(); i++ )
        {
            delete children[ i ];
        }
    }

    Component *getChild( const unsigned int index )
    {
        return children[ index ];
    }

    void add( Component *component )
    {
        children.push_back( component );
    }

    void remove( const unsigned int index )
    {
        Component *child = children[ index ];
        children.erase( children.begin() + index );
        delete child;
    }

    void operation()
    {
        for ( unsigned int i = 0; i < children.size(); i++ )
        {
            children[ i ]->operation();
        }
    }

private:
    std::vector<Component*> children;
};

/*
 * Leaf
 * defines the behavior for the elements in the composition,
 * it has no children
 */
class Leaf : public Component
{
public:
    Leaf( const int i ) : id( i ) {}

    ~Leaf() {}

    void operation()
    {
        std::cout << "Leaf "<< id <<" operation" << std::endl;
    }

private:
    int id;
};


int main()
{
    Composite composite;

    for ( unsigned int i = 0; i < 5; i++ )
    {
        composite.add( new Leaf( i ) );
    }

    composite.remove( 0 );
    composite.operation();

    return 0;
}

Output

Leaf 1 operation
Leaf 2 operation
Leaf 3 operation
Leaf 4 operation

When to Use Composite Pattern

  • Use the Composite pattern when you have to implement a tree-like object structure.
  • Use the pattern when you want the client code to treat both simple and complex elements uniformly.

Comments