Lecture
No.14 CS 304 oop
No.14 CS 304 oop
Consider
the following implementation of the student class we discussed in previous
lectures,
the following implementation of the student class we discussed in previous
lectures,
Composition
If one object is part of another object
(relationship of part and whole) in composition lifetime of one object depends
upon the other. The part objects are essential components of the whole.
(relationship of part and whole) in composition lifetime of one object depends
upon the other. The part objects are essential components of the whole.
For example person is composed of hands,
eyes, feet so on.
eyes, feet so on.
In student class we assigning dynamic memory for
variable name using new operator as shown,
variable name using new operator as shown,
class
Student{
Student{
private:
float gpa;
char * name;
int rollNumber;
public:
Student(char * = NULL, int = 0, float = 0.0);
Student(const Student & st);
const char * GetName() const;
// never return handle of private data
members or private member functions
members or private member functions
~Student();
…
};
Student::Student(char
* _name, int roll, float g)
* _name, int roll, float g)
{
cout <<
"Constructor::Student..\n";
"Constructor::Student..\n";
if (!_name){
name = new
char[strlen(_name)+1];
char[strlen(_name)+1];
strcpy(name,_name);
}
else name = NULL;
rollNumber = roll;
gpa = g;
}
Student::Student(const
Student & st){
Student & st){
if(str.name != NULL){
name = new char[strlen(st.name) + 1];
strcpy(name, st.name);
}
else name = NULL;
rollNumber = st.roll;
gpa = st.g;
}
const char * Student::GetName(){
return name;
}
// never return handle of private data
members or private member functions const ensures that private data members
will not be changed
members or private member functions const ensures that private data members
will not be changed
Student::~Student(){
delete [] name; // deleting name
array
array
}
In
C++ “it is all about code reuse”
C++ “it is all about code reuse”
Composition is Creating objects of one class inside another
class
class
“Has
a”
relationship:
a”
relationship:
Bird
has a beak
has a beak
Student
has a name
has a name
Composition
Now
we change code slightly replacing name char * by String so that it is whole
object of class String as it qualifies to be an object because we have to apply
many operations on it like string dynamic creation and deletion, string copy
using deep copy, searching a substring and so on….
we change code slightly replacing name char * by String so that it is whole
object of class String as it qualifies to be an object because we have to apply
many operations on it like string dynamic creation and deletion, string copy
using deep copy, searching a substring and so on….
Conceptual
notation:
notation:
Composition
Now we see string class code to see how it
simplifies original Student object and how we have used composition here,
simplifies original Student object and how we have used composition here,
class
String{
String{
private:
char * ptr;
public:
String(); // default constructor
String(const String &); // copy
constructor
constructor
void SetString(const char *); //
setter function
setter function
const
char * GetString() const;
char * GetString() const;
//
getter function returning const pointer to data member ptr
getter function returning const pointer to data member ptr
~String()
…
};
String::String(){
cout <<
"Constructor::String..\n";
"Constructor::String..\n";
ptr = NULL;
}
String::String(const String & str){
if(str.ptr != NULL){
ptr = new char[strlen(str.ptr)+1];
strcpy(ptr, str.ptr);
}
else ptr = NULL;
}
void String::SetString(const char * str){
if(ptr
!= NULL){
!= NULL){
delete [] ptr;
ptr = NULL;
}
if(str != NULL){
ptr = new
char[strlen(str)+1];
char[strlen(str)+1];
strcpy(ptr, str);
}
}
issue
of memory leakage (inaccessible memory)
of memory leakage (inaccessible memory)
if
we simply set pointer here
we simply set pointer here
memory
will be outside of our object many cause problems later
will be outside of our object many cause problems later
user
still has pointer of passed value it can itself modify it
still has pointer of passed value it can itself modify it
We
resolve these two issues in SetString by allocating new memory and deleting
previous memory.
resolve these two issues in SetString by allocating new memory and deleting
previous memory.
const
char * String::GetString()const{
char * String::GetString()const{
return ptr;
}
String::~String(){
delete [] ptr;
cout <<"Destructor::String..\n";
}
Make
pointer equal to NULL as well any where you delete dynamic memory.
pointer equal to NULL as well any where you delete dynamic memory.
Now
consider the code of Student class again, now by adding composed string object
our code has been simplified very much, (we will use methods of composed object
simply by calling them where needed)
consider the code of Student class again, now by adding composed string object
our code has been simplified very much, (we will use methods of composed object
simply by calling them where needed)
class
Student{
Student{
private:
float gpa;
int rollNumber;
String name;
public:
Student(char* =NULL, int=0,float=0.0);
Student(const Student &);
void SetName(const char *);
String GetName() const;
const char * GetNamePtr() const;
~Student();
…
};
Student
::Student(char * _name, int roll,
float g){
::Student(char * _name, int roll,
float g){
cout
<<"Constructor::Student..\n";
<<"Constructor::Student..\n";
name.SetString(_name);
rollNumber = roll;
gpa = g;
}
Student::Student(const
Student & s){
Student & s){
name.SetString(s.name.GetString());
gpa = s.gpa;
rollNumber = s.rollNumber;
}
Explanation:
- name.SetString(s.name.GetString());
// setting
composed name of newly created object
composed name of newly created object
- name.SetString(s.name.GetString());
//accessing the
composed object string name of object to be copied
composed object string name of object to be copied
- name.SetString(s.name.GetString());
//accessing the
value of composed object string name by calling its member function GetString
value of composed object string name by calling its member function GetString
- name.SetString(s.name.GetString());
//overall result
: the value of composed object string of object to be copied will be copied to
newly created object composed object string.
: the value of composed object string of object to be copied will be copied to
newly created object composed object string.
const
char * Student::GetNamePtr() const{
char * Student::GetNamePtr() const{
return name.GetString();
}
void Student::SetName(const char * n){
name.SetString(n);
}
Student::~Student(){
cout <<"Destructor::Student..\n";
}
void
main(){
main(){
Student *aStudent=new Student("Fakhir",
899, 3.1);
899, 3.1);
cout << endl;
cout << “Name:” <<
aStudent->GetNamePtr() << “\n”;
aStudent->GetNamePtr() << “\n”;
}
Output:
Constructor::String..Constructor::Student..Name: |
Important Points:
- We can access methods of composed object in the same way as we can
access methods of other objects.
Name of composed object.MemberFunction
- Member functions of a class can access its private data members like,
Student::Student(const
Student & s){
Student & s){
name.SetString(s.name.GetString());
// accessing
private member String name of student using its object s and then
accessing String name member function GetString to access string
value two methods calss in one line
private member String name of student using its object s and then
accessing String name member function GetString to access string
value two methods calss in one line
gpa = s.gpa;
// accessing
private members of student in student member function
private members of student in student member function
rollNo = s.rollNo;
// accessing
private members of student in student member function
private members of student in student member function
}
Constructors
& Composition
Constructors
of the sub-objects are always executed before the constructors of the master
class
of the sub-objects are always executed before the constructors of the master
class
Example:
As
you see the example output of program given above,
you see the example output of program given above,
Output:
Constructor::String..Constructor::Student..Name: |
Constructor
for the sub-object name is executed before the constructor of Student and
destructor of sub-object is called after destructor of student. It is logical
as composing object has to contain composed object so composed object should be
created first and then composing object. Similarly while destructing objects we
composing object is destructed first and then composed object as shown in
diagram below,
for the sub-object name is executed before the constructor of Student and
destructor of sub-object is called after destructor of student. It is logical
as composing object has to contain composed object so composed object should be
created first and then composing object. Similarly while destructing objects we
composing object is destructed first and then composed object as shown in
diagram below,
Composition
Constructor
calling:
calling:
Constructors
are called from composed objects to composing objects.
are called from composed objects to composing objects.
Destructor
calling:
calling:
Destructors
are called from composing objects to composed objects.
are called from composing objects to composed objects.
Post a Comment
Don't Forget To Join My FB Group VU Vicky
THANK YOU :)