Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
25 views

Module_3_Contructors Destructors and Inheritance_Lecture Notes

best notes

Uploaded by

Varun S
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views

Module_3_Contructors Destructors and Inheritance_Lecture Notes

best notes

Uploaded by

Varun S
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

MODULE 3: Constructors, Destructors and Inheritance

CONSTRUCTORS
A constructor is a special member function whose task is to initialize the objects of its class. Constructor is
invoked whenever an object of its associated class is created.
Example:
// class with a constructor
Class integer
{
int m, n;
public:
integer(void); // constructor declared
………
………
};

integer :: integer(void) // constructor defined


{
m=0, n=0;
}
When a class contains a constructor it is guaranteed that an object created by the class will be initialized
automatically.
integer i1; // object int1 created
object i1 of type integer is created and also initializes its data members m and n to zero.

Rules/Characteristics of constructor
1. They should be declared in the public section.
2. They are invoked automatically when the objects are created.
3. They do not have return types, not even void therefore and they cannot return values.
4. They cannot be inherited, though a derived class can call the base class constructor.
5. They can have default arguments.
6. Constructors cannot be virtual.
7. We cannot refer to constructor addresses.
8. An object with a constructor cannot be used as s member of a union.
9. They make implicit calls to the operators new and delete when memory allocation is required.
Types of Constructors
1. Default Constructors
2. Parameterized Constructors
3. Copy Constructors
Default Constructors
A constructor that accepts no parameters is called default constructor. If default constructors are not defined
compiler supplies a default constructor.
Class integer
{
int m, n;
public:
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
integer(); // constructor declared
};

integer :: integer() // constructor defined


{
m=0, n=0;
}

Parametrized Constructors
The constructors that can take arguments are called as parameterized constructors. These constructors are used to
initialize the various data elements of different objects with different values when they are created.
Example:
class integer
{
int m, n;
public:
integer(int x, int y); //parameterized constructor
………
………
};
integer :: integer(int x, int y)
{
m=x;
n=y;
}

For a parameterized constructor object declaration like


integer i1;
will not work. We must pass the initial values as arguments to the constructor function when an object is declared.
This can be done in two ways
 By calling the constructor explicitly
 By calling the constructor implicitly
integer i1 = integer (0,100); //explicit call
integer i1 (10,100); //implicit call

Copy Constructors
A copy constructor is a member function that initializes an object using another object of the same class. In
simple terms, a constructor which creates an object by initializing it with an object of the same class, which has
been created previously is known as a copy constructor.
Copy constructor is used to initialize the members of a newly created object by copying the members of an
already existing object. Copy constructor takes a reference to an object of the same class as an argument.
Example:
Sample(Sample &t)
{
id=t.id;
}
The process of initializing members of an object through a copy constructor is known as copy initialization.
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
#include <iostream>
using namespace std;
class Sample {
int id;

public:
void init(int x) { id = x; }
void display() { cout << endl << "ID=" << id; }
};

int main()
{
Sample obj1;
obj1.init(10);
obj1.display();

// Implicit Copy Constructor Calling


Sample obj2(obj1); // or obj2=obj1;
obj2.display();
return 0;
}

Program: Class with Constructors


#include<iostream>
using namespace std;
class integer
{
int m, n;
public:
integer(int, int); //constructor declared
void display ( )
{
cout<<”m=”<<m<<”/n”;
cout<<”n=”<<n<<”/n”;
}
};

integer :: integer(int x, int y) // constructor defined


{
m=x;
n=y;
}

int main( )
{
integer int1(0,100); //constructor called implicitly
integer int2 = integer(25,75); //constructor called explicitly
cout<<”\NObject1”<<”\n”;
int1.display();
cout<<”\NObject2”<<”\n”;
int2.display();
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
return 0;
}

OUTPUT
Object1
m=0
n=100
Object2
m=25
n=75

The constructors can also be defined as inline functions.


Example:
class integer
{
int m, n;
public:
integer(int x, int y) //inline constructor
{
m=x;
n=y;
}
};

DESTRUCTORS
Destructors are used to destroy the objects that have been created by a constructor. Destructor is a member
function whose name is same as that of class name but it is preceded by a tilde.
Example:
~ integer( ) { }
A destructor never takes any argument nor does it return any value. It will be invoked implicitly by the compiler
upon exit from the program to clean up the storage that is no longer accessible.
Whenever new is used to allocate memory in the constructors, we should use delete to free that memory.
Program to implement Destructor
#include<iostream>
using namespace std;
int count=0;
class alpha
{
public:
alpha()
{
count++;
cout<<”\nNo of object created ”<<count;
}
~alpha()
{
cout<<”\nNo of object destroyed ”<<count;
count--;
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
}
};
int main( )
{
cout<<”\nEnter main\n”;
alpha A1, A2,A3, A4;
{
cout<<”\nEnter block1\n”;
alpha A5;
}
{
cout<<”\nEnter block2\n”;
alpha A6;
}
cout<<”\nRe-enter main\n”;
return 0;
}

Output:
Enter main
No of object created 1
No of object created 2
No of object created 3
No of object created 4
Enter block1
No of object created 5
No of object destroyed 5
Enter block2
No of object created 6
No of object destroyed 6
Re-enter main
No of object destroyed 4
No of object destroyed 3
No of object destroyed 2
No of object destroyed 1

INHERITANCE
The mechanism of deriving a new class from an old one is called inheritance. The old class is referred to as base
class and the new one is called the derived class or subclass. The derived class inherits some or all of the traits
from the base class.
Types of inheritance
Single inheritance: A derived class with only one base class.
Multiple inheritance: A derived class with several base classes.
Multilevel inheritance: The mechanism of deriving a class from another derived class.
Hierarchical inheritance: The traits of one class being inherited by more than one class.
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
Hybrid inheritance: Combination of hierarchical and multiple inheritance.

Defining Derived Class


A derived class can be defined by specifying its relationship with the base class along with its own details. The
general form of defining a derived class is:
class derived-class-name : visibility-mode base-class-name
{
……..//
…….// members of derived class
…….//
};
The colon indicates that the derived-class-name is derived from the base-class-name. The visibility may be either
private or public. The default visibility mode is private. Visibility-mode specifies whether the features of the base
class are privately or publicly derived.
class vehicle : private car //private derivation
{
members of vehicle
}
class vehicle : public car //public derivation
{
members of vehicle
}
class vehicle : car //private derivation by default
{
members of vehicle
}
When the base class is privately inherited by a derived class, ‘public members’ of the base class class
become ‘private members’ of the derived class which means the public members of the base class can only be

Reshma, Dept of CSE


MODULE 3: Constructors, Destructors and Inheritance
accessed by the member functions of the derived class. They are inaccessible to the objects of the derived class.
When the base class is publicly inherited, ‘public members’ of the base class become ‘public members’ of
the derived class and therefore they are accessible to the objects of the derived class.
In both the cases the private members of a base class will never become the members of its derived class.

SINGLE INHERITANCE : PUBLIC


#include<iostream>
using namespace std;
class B
{
int a; //private not inheritable
public:
int b; //public can be inherited by derived class
void get_ab ( );
int get-a ( );
void show_a ( );
};
class D : public test //public derivation
{
int c;
public:
void mul ( );
void display ( );
};
void B :: get_ab ( )
{
a=5;
b=10;
}
int B :: get_a ( )
{
return a;
}
void B :: show_a ( )
{
cout<<”a = “<<a<<”\n”;
}
void D :: mul ( )
{
c = b * get_a ( );
}
void D :: display ( )
{
cout<<”a = “<<get_a ( )<<”\n”;
cout<<”b = “<<b<<”\n”;
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
cout<<”c = “<<c<<”\n”;
}
int main ( )
{
D d;
d.get_ab ( );
d.mul ( );
d.show_a ( );
d.display ( );

d.b = 20;
d.mul ( );
d.display ( );
return 0;
}

Output:
a=5
a=5
b=10
c=50

a=5
b=20
c=100

The class D is publicly derived from base class B. D inherits all the public members of B, so public members of
the base class B is also a public member of the derived class D. The private members of B cannot be inherited by
D. The class D will contain following members as shown

Reshma, Dept of CSE


MODULE 3: Constructors, Destructors and Inheritance
SINGLE INHERITANCE : PRIVATE
#include<iostream>
using namespace std;
class B
{
int a; //private not inheritable
public:
int b; //public ready for inheritance by derived class
void get_ab ( );
int get-a ( );
void show_a ( );
};
class D : private B //private derivation
{
int c;
public:
void mul ( );
void display ( );
};
void B :: get_ab ( )
{
Cout<<”Enter values for a and b:”;
cin>>a>>b;
}
int B :: get_a ( )
{
return a;
}
void B :: show_a ( )
{
cout<<”a = “<<a<<”\n”;
}
void D :: mul ( )
{
get_ab ( );
c = b * get_a ( ); //a cannot be used directly so we are using the function get_a ( )
}
void D :: display ( )
{
show_a ( ); //outputs value of a
cout<<”b = “<<b<<”\n”;
cout<<”c = “<<c<<”\n”;
}
int main ( )
{
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
D d;
d.mul ( );
d.display ( );

d.mul ( );
d.display ( );
return 0;
}

Output:
Enter values for a and b: 5 10
a=5
b=10
c=50

Enter values for a and b: 2 4


a=2
b=4
c=8

The class D is privately derived from base class B. In private derivation, the public members of the base class
becomes private member of the derived class D. So the objects of D cannot have direct access to the public
member functions of B.

The function d.get_ab ( ), d.get_a ( ), d.show_a ( ) will not work in the main function.

MAKING A PRIVATE MEMBER INHERITABLE


Private members of base class cannot be inherited, if we have to inherit it we must change the visibility mode to
public. This would make it accessible to all the other functions of the program, thus taking away the advantage of
data hiding.
There is another visibility modifier protected. A member declared as protected is accessible by the member
functions within its class and any class immediately derived from it. It cannot be accessed by the function outside
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
these two classes. A class can now use all the three visibility modes as illustrated below.
class alpha
{
private: // optional
…… // visible to member functions within its class
public:
…… // visible to all functions in the program
protected:
…… // visible to member functions of its own and derived class
When a protected member is inherited in public mode, it becomes protected in the derived class and it is
accessible by the member functions of the derived class. It is also available for further inheritance. A protected
member inherited in the private mode becomes private in derived class, it is available to the member functions of
the derived class it is not available for further inheritance. Pictorial representation for the two levels of derivation
are shown below.

Normal way of using access specifiers


class x
{
………. // private by default
protected:
……….
public:
……….
}
It is also possible to inherit a base class in protected mode. In this case the public and protected members of the
base class become protected members of the derived class. The table below summarizes how the visibility of the
base class members undergoes modifications in all the three types of derivations.

Reshma, Dept of CSE


MODULE 3: Constructors, Destructors and Inheritance

Visibility of inherited members


MULTILEVEL INHERITANCE

Multilevel inheritance

The class A serves as a base class for derived class B which in turn serves as a base class for derived class C. The
class B is known as intermediate base class since it provides a link for the inheritance between A and C. The chain
ABC is known as inheritance path.
A derived class with multilevel inheritance is declared as follows:
class A { ….. }; //Base class
class B : public A{ ….. }; //B derived from A
class C : public B{ ….. }; //C derived from B
This can be extended to any number of levels.
Example: class student stores roll-number, class test stores the marks obtained in two subjects and class result
contains total marks obtained in the test. The class result can inherit the details of the marks obtained in the test
and the roll-number of students through multilevel inheritance.
#include<iostream>
Using namespace std;
class student
{
protected:
int roll_number;
public:
void get_number ( );
void put_number ( );
};
void student :: get_number (int a )
{
roll_number = a;
}
void student :: put_number ( )
{
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
cout<<”Roll Number: “ <<roll_number << “\n”;
}
class test : public student
{
protected:
float sub1;
float sub2;
public:
void get_marks (float, float );
void put_marks ( );
};
void test :: get_marks (float x, float y )
{
sub1 = x;
sub2 = y;
}
void test :: put_marks ( )
{
cout<<”Marks in SUB1 = “ <<sub1 << “\n”;
cout<<”Marks in SUB2 = “ <<sub2 << “\n”;
}
class result : public test
{
float total;
public:
void display;
};
void result :: display
{
total = sub1 + sub2;
put_number ( );
put_marks ( );
cout<<”Total = “<<total<<”\n”;
}
int main ( )
{
result student1;
student1.get_number (111);
student1.get_marks ( 75.0, 59.5);
student1.display ( );
return 0
}
Output:
Roll Number : 111
Marks in sub1 = 75
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
Marks in sub2 = 59.5
Total = 134.5

MULTIPLE INHERITANCE
A class can inherit the attributes of two or more classes as shown in figure. This is known as multiple inheritance.
It allows the user to combine the features of several existing classes.

Syntax of derived class with multiple base classes is as follows:


class D : visibility B-1, visibility B-1
{
……..
…… //body of D
……
};
Where visibility may be either public or private. The base classes are separated by commas.
Example:
#include<iostream>
Using namespace std;
class M
{
protected:
int m;
public:
void get_m(int);
};
class N
{
protected:
int n;
public:
void get_n(int);
};
class P : public M, public N
{
public:
void display( );
};
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
void M :: get_m( int x)
{
m=x;
}
void N :: get_m( int y)
{
n=y;
}
void P :: display( )
{
cout<< “ m = “<<m<<”\n”;
cout<< “ n = “<<n<<”\n”;
cout<< “ m*n = “<<m*n<<”\n”;
}
int main ( )
{
P p;
p.get_m ( 10);
p.get_n ( 20);
p.display ( );
return 0;
}
OUTPUT
m=10
n=20
m*n=200

In the above program Derived class P contain all the members of M and N in addition to its own members as
shown below.
class P
{
protected:
int m; // from M
int n; // from N
public:
void get_m ( ); // from M
void get_n ( ); // from N
void display ( ); // own member
};

AMBIGUITY RESOLUTION IN INHERITANCE


There might be a problem in using the multiple inheritance, when a function with the same name appears in more
than one base class. Consider the following two classes.
class M

Reshma, Dept of CSE


MODULE 3: Constructors, Destructors and Inheritance
{
public:
void display ( )
{
cout<<”Class M\n”;
}
};
class N
{
public:
void display ( )
{
cout<<”Class N\n”;
}
};
Which display ( ) function is used by the derived class when we inherit these two classes? We can solve this
problem by defining a named instance within the derived class, using the class resolution operator with the
function as shown below:
class P : public M, public N
{
public:
void display( ) // overrides display ( ) of M and N
{
M :: display ( );
}
};
We can now use the derived class as follows:
int main ( )
{
P p;
p.display ( );
}
Ambiguity may also arise in single inheritance applications.
class A
{
public:
void display ( )
{
cout<<”A\n”;
}
};
class B : public A
{
public:
void display ( )
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
{
cout<<”B\n”;
}
};
In the main program we create a object of class B. Call to function display ( ) by B object will invoke a function
defined in B only. To invoke function defined in A we must use scope resolution operator to specify the class.

int main ( )
{
B b;
b.display ( ); // invokes display ( ) in B
b.A :: display ( ); // invokes display ( ) in A
b.B :: display ( ); // invokes display ( ) in B
return 0
}

HIERARCHICAL INHERITANCE
Deriving more than one derived class from a single base class is called as hierarchical inheritance.

Hierarchical classification of students


HYBRID INHERITANCE
Combination two or more types of inheritance is called hybrid
inheritance.

#include<iostream>
Using namespace std;
class student
{
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
protected:
int roll_number;
public:
void get_number ( );
void put_number ( );
};
void student :: get_number (int a )
{
roll_number = a;
}
void student :: put_number ( )
{
cout<<”Roll Number: “ <<roll_number << “\n”;
}
class test : public student
{
protected:
float sub1;
float sub2;
public:
void get_marks (float, float );
void put_marks ( );
};
void test :: get_marks (float x, float y )
{
sub1 = x;
sub2 = y;
}
void test :: put_marks ( )
{
cout<<”Marks in SUB1 = “ <<sub1 << “\n”;
cout<<”Marks in SUB2 = “ <<sub2 << “\n”;
}
class sports
{
protected:
float score;
public:
void get_score ( float s)
{
score=s;
}
void put_score ( )
{
cout<<”Sports “<<score<<”\n”;
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
}
};
class result : public test, public sports
{
float total;
public:
void display;
};
void result :: display
{
total = sub1 + sub2+score;
put_number ( );
put_marks ( );
put_score ( );
cout<<”Total = “<<total<<”\n”;
}
int main ( )
{
result student1;
student1.get_number (111);
student1.get_marks ( 75, 59);
student1.get_score(5);
student1.display ( );
return 0
}
Output:
Roll Number : 111
Marks in sub1 = 75
Marks in sub2 = 59
Score = 5
Total = 139

VIRTUAL BASE CLASS

Multipath Inheritance
In the above example the class Child inherits the properties from 2 base classes Parent1 and Parent2 which is
derived from the common base class Grandparent. It can also inherit the properties of base class Grandparent as
shown by the broken line.
All the public and protected members of Grandparent class are inherited into Child class twice via Parent1
and Parent2. This means that Child class will have duplicate sets of members inherited from Grandparent. This
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
duplication can be avoided by making the common base class as virtual base class while declaring the direct or
intermediate base classes.
When a class is made a virtual base class, C++ sees to that only one copy of that class is inherited
regardless of multiple inheritance path between the virtual base class and a derived class.

Virtual Base Class

Program for Virtual Base Class


#include<iostream>
Using namespace std;
class student
{
protected:
int roll_number;
public:
void get_number ( );
void put_number ( );
};
void student :: get_number (int a )
{
roll_number = a;
}
void student :: put_number ( )
{
cout<<”Roll Number: “ <<roll_number << “\n”;
}
class test : virtual public student
{
protected:
float sub1;
float sub2;
public:
void get_marks (float, float );
void put_marks ( );
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
};
void test :: get_marks (float x, float y )
{
sub1 = x;
sub2 = y;
}
void test :: put_marks ( )
{
cout<<”Marks in SUB1 = “ <<sub1 << “\n”;
cout<<”Marks in SUB2 = “ <<sub2 << “\n”;
}
class sports: public virtual student
{
protected:
float score;
public:
void get_score ( float s)
{
score=s;
}
void put_score ( )
{
cout<<”Sports “<<score<<”\n”;
}
};
class result : public test, public sports
{
float total;
public:
void display;
};
void result :: display
{
total = sub1 + sub2+score;
put_number ( );
put_marks ( );
put_score ( );
cout<<”Total = “<<total<<”\n”;
}
int main ( )
{
result student1;
student1.get_number (111);
student1.get_marks ( 75, 59);
student1.get_score(5);
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
student1.display ( );
return 0
}
Output:
Roll Number : 111
Marks in sub1 = 75
Marks in sub2 = 59
Score = 5
Total = 139

CONSTRUCTORS IN DERIVED CLASSES


If any base class constructor contains a constructor with one or more arguments then it is mandatory for the
derived class to have a constructor and pass the arguments to the base class constructors. If both the derived class
and base classes contain constructors the base class constructor is executed first and then the constructor in the
derived class is executed.
In multiple inheritance, the base classes are constructed in the order in which they appear in the declaration
of the derived class. In multilevel inheritance the constructors will be executed in the order of the inheritance.
The general form of defining a derived constructor is:
Derived_constructor (arglist1, arglist2,…….., arglistN, arglist(D):
base1(arglist1),
base2(arglist2),
……
baseN(arglistN),
{
Body of derived constructor
}
The header line of Derived_constructor function contains two parts separated by a colon ( : ), the first part
provides the declaration of the arguments that are passed to the Derived_constructor and the second part list the
function calls to the base constructors. base1(arglist1), base2(arglist2) are function calls to base constructors
base1( ), base2 ( ) and the arglist1, arglist2 represent the actual parameters that are passed to the base constructors.
arglistD provides parameters that are necessary to initialize the members of the derived class.

Methods of Inheritance

Reshma, Dept of CSE


MODULE 3: Constructors, Destructors and Inheritance
Program for constructors in Derived Class
#include<iostream>
using namespace std;
class alpha
{
int x;
public:
alpha ( int i)
{
x = i;
cout<< “alpha initialized\n”;
}
void show_x ( )
{
cout<< “ x = ”<< x << “\n”;
}
};
class beta
{
float y;
public:
beta ( float j)
{
y = j;
cout<< “beta initialized\n”;
}
void show_x( )
{
cout<< “ y = ”<< y << “\n”;
}
};
class gamma : public beta, public alpha
{
int m, n;
public:
gamma(int a, float b, int c, int d):
alpha (a), beta (b)
{
m = c;
n = d;
cout<< “gamma initialized\n”;
}
void show_mn( )
{
cout<< “ m = ”<< m << “\n” << “ n = ”<< n << “\n;
Reshma, Dept of CSE
MODULE 3: Constructors, Destructors and Inheritance
}
};
int main()
{
gamma g(5, 10.75, 20, 30);
cout<< “\n”;
g.show_x( );
g.show_y( );
g.show_mn( );
return 0;
}

Output
beta initialized
alpha initialized
gamma initialized

x=5
y = 10.75
m = 20
n = 30

beta is initialized first even though it appears second in the derived constructor, because it has been declared first
in the derived class header line. Also alpha(a) and beta(b) are function calls therefore parameters should not
include types.

Reshma, Dept of CSE


MODULE 3: Constructors, Destructors and Inheritance

Reshma, Dept of CSE

You might also like