CPP Aggregation and Delegation
What is Aggregation and Delegation in C++?
- You can look at Aggregation as an alternative inheritance type not as a "is-a" relationship, but a "has-a" relationship to objects in a class.
-
This is to declare objects as a members of another class, which can says
to be the containing class of those members.
class Name { // Declaration and Implementation for Name Class }; class Address { // Declaration and Implementation for Address Class }; . . . . class Employee { // Aggregated objects in form of a "has-a" relationship Name EmpName; Address EmpAddress; // Any other Employee Class stuff... }
- A containing class that aggregates other objects does not have special access to those object's member data and methods, as the existing possibility for "is-a" relationship.
-
Delegation is to use the members of an aggregated class
to perform functions for the containing class.
Aggregate Inheritance and Delegation using a Linked List example:
#include <string> #include <iostream> using namespace std; // BaseObject class must be a base class // for all objects handle by the linked list class BaseObject { protected: // The name is protected and can then be changed // by a drived class string name; public: // Make destructor virtual for all derived Classes // so cleanup can be done in those derived Classes virtual ~BaseObject() {} // Make a pure virtual method that must be implemented // by a driven class and makes this class abstract virtual string getName() const =0; }; // This is the class we want the linked List should handle class Person : public BaseObject { public: Person (string name, int age, int weight){ this->name=name; this->age = age; this->weight = weight; cout << name << " Constructor ...\n"; } ~Person() {cout << name << " Destructor ...\n";} string getName() const { return name; } int getAge() { return age; } int getWeight() { return weight; } private: int age; int weight; }; // In a Linked list we use objects of the Node class // Each Node object contain pointer to an object // driven by the BaseObject class and a pointer to next // Node in the list class Node { private: Node * pNext; BaseObject * baseObject; public: Node( BaseObject * baseObject):pNext(0) { cout << baseObject->getName() << " Node Constructor ...\n"; this->baseObject=baseObject; } ~Node(){ if (pNext!=0) { delete pNext; pNext=0; } cout << baseObject->getName() << " Node Destructor ...\n"; delete baseObject; } BaseObject * getBaseObject() { return baseObject; } Node * getNext() { return pNext; } void setNext(Node * pNext) { this->pNext=pNext; } }; // The NodeManager class is a "worker class" // and is been delegated by the LinkedList class // to manage the linked list class NodeManager { Node * pHead; // pointer to first node in the linked list Node * pLast; // pointer to last node in the linked list int size; // nodes in the list public: NodeManager():pHead(0),pLast(0), size(0) {} ~NodeManager(){ if (pHead!=0) { delete pHead; pHead=0; } } /* Add an Node with an BaseObject pointer to the linked list */ void addNode(BaseObject * baseObject) { Node * p = new Node(baseObject); Node * pTemp=pLast; if (pLast==0) { pHead=p; pLast=p; }else { pLast->setNext(p); pLast=p; } size++; } /* We like to return an array of BaseObject pointer reference that exist in the Linked List instead of the Linked List For this we must return a pointer to pointer to an object driven by the BasObject Class */ BaseObject * * getObjectArray() { BaseObject * * pBaseObject = new BaseObject*[size]; int i=0; Node * pNode=pHead; while ( i < size) { // *(pBaseObject+i)=pNode->getBaseObject(); // this is an alternative coding pBaseObject[i]=pNode->getBaseObject(); i=i+1; pNode = pNode->getNext(); } return pBaseObject; } // return the array size int getSize() {return size;} }; class NodeList { private: // This is a has-a relationship to the NodeManager // that take care of the linked list // It is private and cannot be accessed // without a NodeList object NodeManager nodeManager; public: void addObject(BaseObject * baseObject) { nodeManager.addNode(baseObject); } BaseObject * * getObjectArray() { return nodeManager.getObjectArray(); } // return the array size int getSize() {return nodeManager.getSize();} }; int main () { NodeList nodeList; nodeList.addObject(new Person("Ricard",20,60)); nodeList.addObject(new Person("Frank",22,62)); nodeList.addObject(new Person("Obama",26,76)); Person * * persons = (Person* *)nodeList.getObjectArray(); cout << "\n"; for (int i=0 ; i < nodeList.getSize() ; i++) { // (*(persons+i))->getName(); is the same as persons[i]->getName(); string name=persons[i]->getName(); cout << name << " is " << persons[i]->getAge() << " old "; cout << "and has a weight of " << persons[i]->getWeight() << "\n"; } cout << "\n"; return 0; }
Ricard Constructor ... Ricard Node Constructor ... Frank Constructor ... Frank Node Constructor ... Obama Constructor ... Obama Node Constructor ... Ricard is 20 old and has a weight of 60 Frank is 22 old and has a weight of 62 Obama is 26 old and has a weight of 76 Obama Node Destructor ... Obama Destructor ... Frank Node Destructor ... Frank Destructor ... Ricard Node Destructor ... Ricard Destructor ...
© 2010 by Finnesand Data.
All rights reserved.
This site aims to provide FREE programming training and technics.
Finnesand Data as site owner gives no warranty for the
correctness in the pages or source codes.
The risk of using this web-site pages or any program
codes from this website is entirely at the individual user.