1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Association, Aggregation and Composition Relationships with Examples

Discussion in 'C++' started by Mridula, May 1, 2009.

  1. Mridula

    Mridula New Member

    Joined:
    Mar 5, 2008
    Messages:
    316
    Likes Received:
    19
    Trophy Points:
    0
    Occupation:
    S/w proffessional
    Location:
    Bangalore
    This article talks about Association, Aggregation and Composition Relationships between classes with some C++ examples.

    Background



    Association is a simple structural connection or channel between classes and is a relationship where all objects have their own lifecycle and there is no owner.

    Lets take an example of Department and Student.

    Multiple students can associate with a single Department and single student can associate with multiple Departments, but there is no ownership between the objects and both have their own lifecycle. Both can create and delete independently.

    Here is respective Model and Code for the above example.

    [​IMG]

    The code



    Code:
    #include<iostream.h>
    
    class Student;
    
    class Department
    {
        char* name_p;
      
      public:
    
        Department(char *dName)
        {
          cout<<"Department::ctor\n";
          name_p = new char(sizeof(strlen(dName)));
          name_p = dName;
        }
    
        char* dName() const
        {
          return(name_p);
        }
    
        ~Department()
        {
          cout<<"Department::dtor\n";
          delete(name_p);
        }
    
    };
    
    class Student
    {
      char* name_p;
    
      public:
    
        Student(char *sName)
        {
          cout<<"Student::ctor\n";
          name_p = new char(sizeof(strlen(sName)));
          name_p = sName;
        }
    
        char* sName()const
        {
          return(name_p);
        }
        
        ~Student()
        {
          cout<<"Student::dtor\n";
          delete(name_p);
        };
    };
    
    
    class Course
    {
        Student * std_p;
        Department * dept_p;
        char * courseName_p;
    
        static unsigned int index;
        static Course *courseList[4];
    
      public:
        
        Course(char* crseName, Student* student, Department* dept):
          courseName_p(0), std_p(student), dept_p(dept)
        {
          cout<<"Course:ctor\n";
    
          if (index < 4)
          {
            courseName_p = new char(sizeof(strlen(crseName)));
            courseName_p = crseName;
            
            //insert this Course in courseList
            courseList[index] = this;
            ++index;
          }
          else
          {
            cout<<"Cannot accomodate any more Course\n";
          }
        };
    
        ~Course()
        { 
          cout<<"Course:dtor\n";
          delete (courseName_p);
        };
    
        static char* findStudent(char *crseName, char* deptName)
        {
          for(int i=0; i<index; i++)
          {
            if ( (courseList[i]->getCourseName() == crseName) && 
                 (courseList[i]->getDeptName() == deptName) )
            {
              return(courseList[i]->getStdName());
            }
          }
        }
    
        char * getStdName()const {return(std_p->sName());};
        char * getDeptName() const {return(dept_p->dName());};
        char * getCourseName()const {return(courseName_p);};
    }; 
    
    unsigned int Course::index =0;
    Course* Course::courseList[4] = {0,0,0,0};
    
    
    int main()
    {
      int i;
    
      cout<<"\nExample of Association class...\n";
      cout<<"-----------------------------------\n\n";
    
      cout<<"We have got 4 students ...\n";
      Student *studentNames[4] = {new Student("Meera"), new Student("Moina"), new Student("Teena"), new Student("Mridula")} ;
    
      cout<<"\n";
    
      cout<<"We have got 2 Departments...\n";
      Department *departNames[2] = {new Department("Mathemetics"), new Department("ComputerSceince")} ;
      
      cout<<"\n";
    
      cout<<"Here class Course Associates Student and Department, with a Course name ...\n";
      Course course1("DataStructure",studentNames[0], departNames[1]);
      Course course2("Maths",studentNames[3], departNames[0]);
      Course course3("Geometry",studentNames[2], departNames[0]);
      Course course4("CA",studentNames[1], departNames[1]);
    
      cout<<"\n";
    
      cout<<"Finding a Student using Course and Department...\n";
      cout<<"Student who has taken Maths Course in Mathemetics Department is:"<<Course::findStudent("Maths", "Mathemetics")<<endl;
      
      cout<<"\n";
    
      cout<<"Deletion of objects...\n\n";
    
      for(i=0; i<4; ++i)
      {
        delete studentNames[i];
      }
    
      cout<<"\n";
    
      for(i=0; i<2; ++i)
      {
        delete departNames[i];
      }
    
      cout<<"\n";
    
      return(0);
    }
    
    output:
    ------
    
    Example of Association class...
    -----------------------------------
    
    We have got 4 students ...
    Student::ctor
    Student::ctor
    Student::ctor
    Student::ctor
    
    We have got 2 Departments...
    Department::ctor
    Department::ctor
    
    Here class Course Associates Student and Department, with a Course name ...
    Course:ctor
    Course:ctor
    Course:ctor
    Course:ctor
    
    Finding a Student using Course and Department...
    Student who has taken Maths Course in Mathemetics Department is:Mridula
    
    Deletion of objects...
    
    Student::dtor
    Student::dtor
    Student::dtor
    Student::dtor
    
    Department::dtor
    Department::dtor
    
    Course:dtor
    Course:dtor
    Course:dtor
    Course:dtor
    
    Aggregation is a specialize form of Association where all object have their own lifecycle but there is a ownership like parent and child. Child object can not belong to another parent object at the same time. We can think of it as "has-a" relationship.

    Implementation details:
    1. Typically we use pointer variables that point to an object that lives outside the scope of the aggregate class
    2. Can use reference values that point to an object that lives outside the scope of the aggregate class
    3. Not responsible for creating/destroying subclasses
    Lets take an example of Employee and Company.

    A single Employee can not belong to multiple Companies (legally!! ), but if we delete the Company, Employee object will not destroy.

    Here is respective Model and Code for the above example.

    [​IMG]

    The code



    Code:
    #include<iostream.h>
    
    class Employee
    {
      public:
    
        Employee(char *name){
          cout<<"Employee::ctor\n";
          myName_p = new char(sizeof(strlen(name)));
          myName_p = name;
        }
        
        char* disp(){return(myName_p);};
    
        ~Employee()
        {
          cout<<"Employee:dtor\n\n";
          delete (myName_p);
        }
    
      private:
        char *myName_p;
    };
    
    class Company
    {
      public:
        Company(char * compName, Employee* emp){
          cout<<"Company::ctor\n";
          name = new char(sizeof(strlen(compName))); 
          name = compName;
          myEmp_p = emp;
        };
    
        ~Company()
        {
          cout<<"Company:dtor\n\n";
          myEmp_p = NULL;
        };
        
      private:
        char *name;
        Employee *myEmp_p;
    };
    
    
    int main()
    {
      cout<<"\nExample of Aggregation Relationship \n";
      cout<<"-----------------------------------------\n\n";
        
      {
        cout<<"Here, an Employee-Keerti works for Company-MS \n";
        Employee emp("Keerti");
      
        {
          Company comp("MS", &emp);
        } // here Company object will be deleted, whereas Employee object is still there
    
        cout<<"At this point Company gets deleted...\n";
        cout<<"\nBut Employee-"<<emp.disp();
        cout<<" is still there\n";
        
      } //here Employee object will be deleted
    
      return(0);
    }
    
    output:
    -------
    
    Example of Aggregation Relationship 
    -----------------------------------------
    
    Here, an Employee-Keerti works for Company-MS 
    Employee::ctor
    Company::ctor
    Company:dtor
    
    At this point Company gets deleted...
    
    But Employee-Keerti is still there
    Employee:dtor
    
    
    Composition is again specialize form ofAggregation. It is a strong type of Aggregation. Here the Parent and Child objects have coincident lifetimes. Child object dose not have it's own lifecycle and if parent object gets deleted, then all of it's child objects will also be deleted.

    Implentation details:

    1. Typically we use normal member variables
    2. Can use pointer values if the composition class automatically handles
    allocation/deallocation
    3. Responsible for creation/destruction of subclasses

    Lets take an example of a relationship between House and it's Rooms.

    House can contain multiple rooms there is no independent life for room and any room can not belong to two different house. If we delete the house room will also be automatically deleted.

    Here is respective Model and Code for the above example.

    [​IMG]

    The code



    Code:
    #include<iostream.h>
    
    class House;
    
    class Room
    {
      public:
    
        Room()
        {
        };
    
        static void createRoom_v(Room* (&room), House* hse, char* name)
        {
          room = new Room(hse, name); 
        }
        
        Room(House* hse, char* myName)
        {
          cout<<"Room::ctor\n";
          myHse_p = hse;
          
          if(NULL != myHse_p)
          {
            name_p = new char(sizeof(strlen(myName)));
            name_p = myName;
          }
          else
          {
            cout<<"Oops House itself is not Created Yet ...\n";
          }
        };
    
        ~Room()
        {
          cout<<"Room:dtor\n";
          myHse_p = NULL;
          delete (name_p);
        };
    
        void disp()
        {
          cout<< name_p;
          cout<<"\n";
        }
        
        static void initList_v(Room *(& roomsList_p)[3])
        {
          roomsList_p[3] = new Room[3];
        }
    
      private:
        House * myHse_p;
        char * name_p;
    };
    
    class House
    {
      public:
    
        House(char *myName)
        {
          cout<<"House::ctor\n";
          name_p = new char(sizeof(strlen(myName)));;
          name_p = myName;
    
          Room::initList_v(roomsList_p);
    
          Room* myRoom;
          Room::createRoom_v(myRoom, this, "Kitchen");
          roomsList_p[0] = myRoom;
          
          Room::createRoom_v(myRoom, this, "BedRoom");
          roomsList_p[1] = myRoom;
    
          Room::createRoom_v(myRoom, this, "Drwaing Room");
          roomsList_p[2] = myRoom;
        }
        
        ~House()
        {
          cout<<"House:dtor\n";
          unsigned int i;
          
          cout<<"Delete all the Rooms ...\n";
          for(i=0; i<3; ++i)
          {
            if(roomsList_p[i] != NULL)
            {
              delete (roomsList_p[i]);
            }
              
          }
          delete [] roomsList_p;
          delete (name_p);
        }
    
        void disp()
        {
          cout<<"\n\nName of the House :"<<name_p;
          
          if(roomsList_p != NULL)
          {
            unsigned int i;
            cout<<"\n\nRooms details...\n";
            for(i=0; i<3; ++i)
            {
              if(NULL != roomsList_p[i])
              {
                roomsList_p[i]->disp();
              }
            }
            cout<<"\n\n";
          }
        }
    
      private:
        char* name_p;
        Room* roomsList_p[3];
    };
    
    int main()
    {
      
      cout<<"\nExample of Composition Relationship\n";
      cout<<"-----------------------------------------\n\n";
      House hse("Vishranti Nilaya");
    
      cout<<"\n\nHouse details...\n";
      hse.disp();
    
      cout<<"Here House itself creates the Rooms and Deletes as well, before it gets deletd...\n";
    
      return(0);
    }
    
    output:
    -------
    Example of Composition Relationship
    -----------------------------------------
    
    House::ctor
    Room::ctor
    Room::ctor
    Room::ctor
    
    
    House details...
    
    
    Name of the House :Vishranti Nilaya
    
    Rooms details...
    Kitchen
    BedRoom
    Drwaing Room
    
    
    Here House itself creates the Rooms and Deletes as well, before it gets deletd...
    House:dtor
    Delete all the Rooms ...
    Room:dtor
    Room:dtor
    Room:dtor
    
    These relationships can also be explained with simple examples as below
    (these lines I have read in some blog):

    Association:

    1. Create a folder called "Links"
    2. Create a shortcut/link inside this folder and link it to www.go4expert.com
    3. Create another shortcut/link instide this folder and link it to www.google.com
    4. Ask your friend to do the same on another machine using same links (www.go4expert.com and www.google.com)
    5. Delete the "Links" folder, and open your browser to check if www.go4expert.com and www.google.com still exist or not ;)
    Briefly, Association is a relationship where all the objects have different lifecycles. there is no owner.

    Aggregation:

    1. Create a file called file.txt
    2. Make a simple Application to open the File.txt (rw mode), but don't program it close the connection.
    3. Run an instance of this application (it should work ok and can open the file for rw)
    4. Keep the first instance, and run another instance of this application (In theory it should complain that it can't open the file in rw mode because it is already used by other application).
    5. Close the 2 instances (make sure you close the connection).
    From the above application, we understand that the Application and the File has a separate lifecycles, however this file can be opened only by one application simuletanously (there is only one parent at the same time, however, this parent can move the child to another parent or can make it orphan).

    Composition:

    1. Open a new Document name it as test.txt
    2. Write this sentence inside this document "This is a composition".
    3. Save the document.
    4. Now, delete this document.

    This is what is called composition, you can't move the sentence "This is a omposition" from the document because its lifecycle is linked to the parent (i.e. the document here !!)
     
    SaswatPadhi likes this.
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,283
    Likes Received:
    364
    Trophy Points:
    83
    Really nice example of go4expert.com and google.com
     
  3. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,283
    Likes Received:
    364
    Trophy Points:
    83
  4. Amar_Raj

    Amar_Raj New Member

    Joined:
    Jun 17, 2009
    Messages:
    34
    Likes Received:
    0
    Trophy Points:
    0
    Occupation:
    Dev
    Location:
    Namma Bengaluru
    Hi Mridula,

    Very good article and simple analogy as examples.
    But there is one minor mistake - The composition relationship should be graphically represented by "Solid Diamond" and not with "hollow Diamond" which is for Aggregation relationship.

    Sharanu ;),
    Amar
     
  5. Mridula

    Mridula New Member

    Joined:
    Mar 5, 2008
    Messages:
    316
    Likes Received:
    19
    Trophy Points:
    0
    Occupation:
    S/w proffessional
    Location:
    Bangalore
    Hi Amar,

    Many thanks for your comment!!
    Yes. The solid diamond should have been there for composition. It is just missed. Some tools does not provide that. so.

    thanks,
    mridula.
     
  6. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,283
    Likes Received:
    364
    Trophy Points:
    83
  7. RRT2010

    RRT2010 New Member

    Joined:
    Apr 7, 2011
    Messages:
    8
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    India
    Hi Mridula,its a really nice article. The examples are really nice. Thanks for sharing :)
     
  8. msdnguide

    msdnguide New Member

    Joined:
    May 14, 2011
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    Occupation:
    msdnguide
    Location:
    Delhi
    Home Page:
    Wow....too good. I am preparing for C++ inreview and this info is very useful
     
  9. sriprasanna

    sriprasanna New Member

    Joined:
    Jun 19, 2012
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    Hi Mridula,
    The information provided here was really useful in understanding those concepts with no pain.. Thanks.. and may I know which tool you have used to create the class diagrams?
     
  10. someshsaraf

    someshsaraf New Member

    Joined:
    Oct 30, 2010
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    This is a quite good article.
    The point I did not understand was the ownership difference between Aggregation and Association.

    I find lot of different definitions of association and aggregation where aggregation is terms where no ownership exists.

    Also, in the above examples of association and aggregation I thought setting myEmp_p = NULL; is not appropriate. Is this to show ownership?
     

Share This Page