Composite Design Pattern in C++

Composite pattern is one of the most widely used patterns in the industry and addresses a very significant and subtle problem. It is used whenever the user wants to treat the individual object in the same way as the collection of those individual objects for e.g you might want to consider a page from the copy as same as the whole copy which is basically a collection of the pages or if you want to create a hierarchy of something where you might want to consider the whole thing as the object .
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

In the case of photoshop where we draw many individual objects and then those objects compose a whole unique object and you might want to apply some operation on the whole object instead of the each of the individual objects.

Here in this diagram, as you can see both composite and Leaf implements Component diagram, thus allowing the same operation on both objects but the important part is Composite Class which also contain the Component Objects which is symbolized by the black diamond indicating composition relationship between Composite and Component class.

Then how to design our classes to accommodate such scenarios. We will try to understand it by implementing our copy example. Say you have to create a page which has operations like add, delete, remove and also a copy which will have the same operations as the individual pages.

Such situation is the best dealt with the composite pattern.

// CPP program to illustrate

// Composite design pattern

#include <iostream>

#include <vector>

usingnamespacestd;

classPageObject {

public:

virtualvoidAdd(PageObject a)

{

}

virtualvoidRemove()

{

}

virtualvoidDelete(PageObject a)

{

}

};

classPage : publicPageObject {

public:

voidAdd(PageObject a)

{

cout << "something is added to the page"<< endl;

}

voidRemove()

{

cout << "soemthing is removed from the page"<< endl;

}

voidDelete(PageObject a)

{

cout << "soemthing is deleted from page "<< endl;

}

};

classCopy : publicPageObject {

vector<PageObject> copyPages;

public:

voidAddElement(PageObject a)

{

copyPages.push_back(a);

}

voidAdd(PageObject a)

{

cout << "something is added to the copy"<< endl;

}

voidRemove()

{

cout << "something is removed from the copy"<< endl;

}

voidDelete(PageObject a)

{

cout << "something is deleted from the copy";

}

};

intmain()

{

Page a;

Page b;

Copy allcopy;

allcopy.AddElement(a);

allcopy.AddElement(b);

allcopy.Add(a);

a.Add(b);

allcopy.Remove();

b.Remove();

return0;

}

something is added to the copy
something is added to the page
something is removed from the copy
soemthing is removed from the page

Now the same operation that can be applied to an individual object and can also be applied to the collection of those individual object makes it very easy to work with a larger object which is made of the smaller independent objects.
The most notable example of the composite pattern is in any UI toolkit. Consider the case of UI elements where each UI top-level UI element is composed of many smaller independent lower-level UI elements and the both the top and lower level UI element respond to same events and actions.

This article is contributed by Ankit Singh. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.