Click here to Skip to main content
13,297,799 members (47,468 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


24 bookmarked
Posted 17 May 2012

Two Ways to Realise the Composite Pattern in C++ and Qt

, 17 May 2012
Rate this:
Please Sign up or sign in to vote.
In this article I show the Object-Oriented Implementation of tree, by using Composite Design Pattern, C++ and Qt Framework. I will also explain why we do not use (although you can) in Qt the standard design of Composite Pattern as described in GoF.


This article shows two ways to compose objects into tree structures to represent part-whole hierarchies. The first example explains how to use a simple Composite pattern of GoF (by using standard C++) and second one focuses on using the Qt Nokia Framework.


The figure below shows a UML class diagram for the Composite Pattern:

For more information about Composite pattern, please see the following article from Wikipedia or see the book of Gamma, Erich; Richard Helm, Ralph Johnson, John M. Vlissides (1995). Design Patterns: Elements of Reusable Object-Oriented Software.

The Way for Using Composite Pattern with Standard C++

OK, now we need to build a tree structure to implement one hierarchy (an organizational structure). An organization can be made up of something like a chief executive officer (CEO) at the top with many different types of managers below him and more employees below the managers. Finally there will be someone in the hierarchy who would be at the leaf level. By leaf we mean someone at the bottom most level. So there are two types of folks, one to whom people report and another to whom no one reports (see the figure at the beginning of article) Let's assume that the client (for example a tax inspector) wants to know about the salaries of this organization. Overall salary is made up of individual salaries therefore all the employees should be able to return their own salary. When it comes to Client who is looking for the salary of any departament (of course, departament may be the whole company) then every employee should be able to return his salary and also the salary of all people under his supervision.

Using the composite pattern design is one of those innovations that would make life easier for people who want to organize the construction of a hierarchical structure.

OK, let's create an UML (class diagram) for our example:

The above diagram represents a leaf node (Worker) and a parent node (Manager). Please note that a Manager could be a CEO, CTO or a VP etc. This is also a very simple example of Inheritance in action with Polymorphism.

Now there are a few things that we need to see carefully in this diagram ­

  • Component: contains only an interface - printSalary a pure virtual method, which has to be implemented by a derived class (Worker & Manager)
  • Manager: contains itself and contains the worker(s). The Manager MUST always be the root of the tree
  • Worker: contains only itself

The following example, written in C++, implements a Component class, which can be either a Worker or a Manager (composition of several Workers). Every component can print his salary.

class Component
    Component(std::string name, double salary) 
          : m_fullName(name), m_valueSalary (salary) {}

    virtual void printSalary(int level) = 0;
    //Of course these data members should be private, 
    //but I did not wish to "litter" this class with 
    //superfluous functions-interfaces,
    //therefore I have left these data members of class to be public
    std::string            m_fullName;
    double                 m_valueSalary;

/** "Leaf" */
class Worker : public Component
    Worker(std::string name , double salary): Component(name,salary)
    void printSalary(int level)
        for(int j=0; j < level; ++j) cout << "\t";
        cout << "Worker : " <<  
            m_fullName.c_str() << ",salary: " << 
            m_valueSalary << "$\n";

/** "Composite" */
class Manager: public Component
    Manager(std::string name , double salary) : Component(name,salary)
    void add(Component *cmp)
    void printSalary(int level)
        for(int j=0; j < level; ++j) cout << "\t";
        cout << "Manager : " <<  this->m_fullName.c_str() << 
            ",salary: " << m_valueSalary << "$\n";

            for(int x=0; x < level; ++x) cout << "\t";
            cout << "Subordinates  of " <<  
                m_fullName.c_str() << ":\n";
            for (int i = 0; i < m_children.size(); ++i)

    // The manager can have a number of people(managers or workers) 
    // under his/her supervision 
    // and that is the reason we have the vector here (for 
    // navigating a hierarchical organisation, 
    // for typing an individual salary)
    vector < Component * > m_children;

int main()
    //Let's define a big chief
    Manager president ("Gerard Butcher", 1000000.0);
    //Let's define several average chiefs
    Manager manager_production_department ("John Smith",400000.0);
    Manager manager_engineering_department ("Michael Biner",400000.0);
    Manager manager_quality_control_department ("David Jaskson",280000.0);
    Manager manager_sales_management_division ("Tom Vilow",270000.0);
    Manager manager_general_affairs_department ("Janet Teyllor" ,200000.0);
    //Let's define several managers of a engineering department
    Manager team_leader_RandD ("Jorge Creig", 250000.0); 
    Manager team_leader_QA ("Arnold Lambero", 200000.0); 
    //Let's define several engineers of a engineering department
    Worker software_developer1 ("Andrey Lapidos", 200000.0);
    Worker software_developer2 ("Maxim  Laertsky", 240000.0);
    Worker tester ("Miki  Minaj", 130000.0);
    //Now we will add the number of persons as assistants of president
    president.add(&manager_general_affairs_department );

    //Now we will add the number of persons as assistants of manager engineering department
    manager_engineering_department.add(&team_leader_QA );

    //Now we will add the number of persons as assistants of team leader the R&D

    //Now we will add the tester as assistant of team leader the QA

    cout << "The hierarchy of the company,\ni.e. president and all who is under his supervision :\n\n" ;

    cout << '\n';                 

The way for using Composite Pattern with Qt4 Cross-Platform Framework

As we know in Qt exists the QObject class. The QObject class is the base class of all Qt objects. QObject derived class can be quite useful because we can express the relationship parent-child between objects of classes inherited from QObject. With this class and its methods (setParent, findChildren and parent), which I will explain below, we can abandon the previous design (with the implementation of two different classes), using instead a new design (with only one class in both cases: Worker and Manager). As in the previous solution, the root of tree (i.e., the top level of an organizational hierarchy) QObject will have lots of children, but no parent. The simplest QObjects (i.e., the leaf nodes of this tree) will each have a parent, but no children. Client code can recursively deal with each node of the tree.
So we will define the class diagram...

The QObject public interface allows us to build up a tree-like representation of the organization with code that instantiates an WorkerOrManager and then calls setParent() to add it to the appropriate child list.

class WorkerOrManager : public QObject
    WorkerOrManager(QString name , double salary)
        m_fullName    = name;
        m_valueSalary = salary;

    void printSalary(int level)
        for(int j=0; j < level; ++j) std::cout << "\t";
        std::cout << "Worker : " <<  
            m_fullName.toStdString() << ",salary: " << 
            m_valueSalary << "$\n";

        QList<WorkerOrManager*> children = 

        //Here, we want to check if the object is a manager
            for(int j=0; j < level; ++j) std::cout << "\t";
            std::cout << "Subordinates  of " << 
                m_fullName.toStdString() << ":\n";

            for (int i = 0; i < children.size(); ++i)
                //We deduce data only about direct subordinates
                if(children[i]->parent() == this)

     QString      m_fullName;
     double       m_valueSalary;

int main(int argc, char *argv[])
    QCoreApplication a(argc, argv);

    //Let's define a big chief
    WorkerOrManager president ("Gerard Butcher", 1000000.0);

    //Let's define several average  chiefs
    WorkerOrManager manager_production_department ("John Smith",400000.0);
    WorkerOrManager manager_engineering_department ("Michael Biner",400000.0);
    WorkerOrManager manager_quality_control_department ("David Jaskson",280000.0);
    WorkerOrManager manager_sales_management_division ("Tom Vilow",270000.0);
    WorkerOrManager manager_general_affairs_department ("Janet Teyllor" ,200000.0);

    //Let's define several managers of a engineering department
    WorkerOrManager team_leader_RandD ("Jorge Creig", 250000.0);
    WorkerOrManager team_leader_QA ("Arnold Lambero", 200000.0);

    //Let's define several engineers of a engineering department
    WorkerOrManager software_developer1 ("Andrey Lapidos", 200000.0);
    WorkerOrManager software_developer2 ("Maxim  Laertsky", 240000.0);
    WorkerOrManager tester ("Miki  Minaj", 130000.0);

    //Now we will add the number of persons as assistants of president

    //Now we will add the number of persons as assistants of manager engineering department

    //Now we will add the number of persons as assistants of team leader the R&D

    //Now we will add the tester as assistant of team leader the QA

    cout << "The hierarchy of the company,\ni.e. president and all who is under his supervision :\n\n" ;

    return a.exec();

Whenever we have two objects QObject (for example objA and objB) and we want to make one object the child of another, we simply call the QObject::setParent

For example, after calling the objB.setParent(objA),the objA will be parent of objB. And by using the QObject::parent() method, we can check who is the parent object

Please note that due to the following method, we can get access to all the descendants of the object:

QList<T> QObject::findChildren ( const QString & name = QString() ) const

As stated in the Qt documentation: "This method returns the children of this object that can be cast to type T and that have names matching the regular expression regExp, or an empty list if there are no such objects. The search is performed recursively"

In brief, by using QObject class and the above mentioned methods, we can abandon the use of standard Composite Pattern and use the specific Qt-design, as described in this section.


Note that in the two cases with different designs we have the same result, i.e. for the same input we get the same output:


  • 10nd April 2012: Initial post


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Volynsky Alex
Software Developer
Canada Canada
Mr.Volynsky Alex is a Software Engineer in a leading software company. Alex is skilled in many areas of computer science. He has over 13 years of experience in the design & development of applications using C/C++/STL, Qt, MFC, DirectShow, JavaScript, VBScript, Bash and of course - C#/.NET.

In addition, Alex is the active member of Intel® Developer Zone (he was awarded by Intel® Green Belt for his active contribution to the Intel Developer Zone community for developers using Intel technology).

Alex is also interested in the Objective-C development for the iPad/iPhone platforms and he is the developer of the free 15-puzzle game on the App Store.

Overall, Alex is very easy to work with. He adapts to new systems and technology while performing complete problem definition research.

His hobbies include yacht racing, photography and reading in multiple genres.
He is also fascinated by attending computer meetings in general, loves traveling, and also takes pleasure in exercising and relaxing with friends.

Visit his C++ 11 blog

You may also be interested in...


Comments and Discussions

QuestionMy vote of 3 Pin
David 'dex' Schwartz22-May-12 3:06
memberDavid 'dex' Schwartz22-May-12 3:06 
AnswerRe: My vote Pin
Volynsky Alex22-May-12 5:13
memberVolynsky Alex22-May-12 5:13 
GeneralRe: My vote Pin
David 'dex' Schwartz22-May-12 13:58
memberDavid 'dex' Schwartz22-May-12 13:58 
GeneralRe: My vote Pin
Volynsky Alex22-May-12 23:33
memberVolynsky Alex22-May-12 23:33 

GeneralMy vote of 3 Pin
Country Man21-May-12 0:13
memberCountry Man21-May-12 0:13 
QuestionAn example all should follow Pin
jfriedman20-May-12 8:39
memberjfriedman20-May-12 8:39 
AnswerRe: An example all should follow Pin
Volynsky Alex20-May-12 8:50
memberVolynsky Alex20-May-12 8:50 
GeneralRe: An example all should follow Pin
jfriedman20-May-12 9:47
memberjfriedman20-May-12 9:47 
GeneralMy vote of 5 Pin
jfriedman20-May-12 8:37
memberjfriedman20-May-12 8:37 
GeneralMy vote of 5 Pin
GlebGeglov19-May-12 23:52
memberGlebGeglov19-May-12 23:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171207.1 | Last Updated 17 May 2012
Article Copyright 2012 by Volynsky Alex
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid