SlideShare a Scribd company logo
MODULE 3
OPERATOR OVERLOADING AND INHERITANCE
INTRODUCTION
 In C++, you can overload most operators so that they perform special operations relative to
classes that you create.
 For example, a class that maintains a stack might overload + to perform a push operation and
– to perform a pop.
 When an operator is overloaded, none of its original meanings are lost.
 It allows the full integration of new class types into the programming environment.
 After overloading the appropriate operators, you can use objects in expressions just the same
way that you use C++'s built-in data types.
 An operator function defines the operations that the overloaded operator will perform relative
to the class upon which it will work.
 An operator function is created using the keyword operator.
 Operator functions can be either members or nonmembers of a class. Nonmember operator
functions are almost always friend functions of the class
INTRODUCTION
 We can overload all the C++ operators except the following:
 Class members access operator (. , .*)
 Scope resolution operator (: :)
 Size operator(sizeof)
 Condition operator (? :)
CREATING A MEMBER OPERATOR FUNCTION
( OPERATOR OVERLOADING)
 To define an additional task to an operator, we must specify what it means in relation to
the class to which the operator is applied.
 This is done with the help of a special function called operator function, which
describes the task
 A member operator function(Operator Overloading) takes this general form:
returntype class-name::operator#(arg-list)
{
// operations
}
• operator functions return an object of
the class they operate on, but returntype
can be any valid type.
• The # is a placeholder. When you create
an operator function, substitute the
operator for the #
CREATING A MEMBER OPERATOR FUNCTION
(OPERATOR OVERLOADING)
 operator functions are declared in. the class using prototypes as follows:-
 vector is a data type of class and may represent both magnitude and direction or a
series of points called elements
• vector operator + (vector); /./ vector addition
• vector operator-( ); //unary minus
• friend vector operator + (vuelor, vector); // vector add
• friend vector operator -(vector); // unary minus
• vector operator - ( vector &a); // substraction
• int operator = =(vector); //comparision
• friend int operator = =(vector ,vrctor); // comparision
CREATING A MEMBER OPERATOR FUNCTION
(OPERATOR OVERLOADING)
 The process of overloading involves the following steps.
1. Create a class that defines the data type used in the overloading operation.
2. Declare the operator function operator op() in the public part of the class
3. It may be either a member function or a friend function.
4. Define the operator function to implement the required operations
Overloaded operator functions can be invoked by expressions such as
• op x or x op; for unary operators
• x op y; for binary operators.
• operator op(x); for unary operator using friend function
• operator op(x,y); for binary operator using friend function
#include <iostream>
using namespace std;
class loc
{
int longitude, latitude;
public:
loc() {}
loc(int lg, int lt)
{
longitude = lg;
latitude = lt;
}
void show()
{
cout << longitude << " ";
cout << latitude << "n";
}
loc operator+(loc op2);
};
loc loc::operator+(loc op2)
{
loc temp;
temp.longitude = op2.longitude + longitude;
temp.latitude = op2.latitude + latitude;
return temp;
}
int main()
{
loc ob1(10, 20), ob2( 5, 30);
ob1.show(); // displays 10 20
ob2.show(); // displays 5 30
ob1 = ob1 + ob2;
ob1.show(); // displays 15 50
return 0;
}
C++ program to overload binary operator
CREATING A MEMBER OPERATOR FUNCTION
(OPERATOR OVERLOADING)
 operator+( ) has only one parameter even though it overloads the binary + operator.
 The reason that operator+( ) takes only one parameter is that the operand on the left
side of the + is passed implicitly to the function through the this pointer.
 The operand on the right is passed in the parameter op2.
 When binary operators are overloaded, it is the object on the left that generates the
call to the operator function.
 As mentioned, it is common for an overloaded operator function to return an object of
the class it operates upon.
 By doing so, it allows the operator to be used in larger expressions.
C++ overloading binary operators(adding two complex numbers)
# include <iostream>
using namespace std;
class complex
{
float x; // real part
float y; // imaginary part
public : complex() { } // constructor 1
complex(float real, float imag) // constructor 2
{
x = real;
y = imag;
}
complex operator + (complex);
void display();
};
complex complex :: operator+(complex c)
{
complex temp; //temporary
temp.x = x + c.x; // these are
temp.y = y + c.y; // statement for float additions
return(temp);
void complex :: display()
{
cout << x << " + j" << y << "n";
}
int main()
{
complex c1, c2, c3;
c1 = complex (2.5, 3.5);
c2 = complex (1.6, 2.7);
c3 = c1 + c2;
cout << "c1 = ";
c1.display();
cout << "c2 = ";
c2.display();
cout << "nc3 = ";
c3.display();
return 0;
}
OVERLOADING UNARY OPERATORS(USING MEMBER FUNCTION)
 Let us consider unary minus operator.
 A minus operator used when as a unary, takes just only one operand.
 We know that this operator changes the sign of an operand when applied to a basic
one operand.
 We will see here how to overload this operator so that it can be applied to an object
in much the same way as is applied to an int or float variable.
 The minus unary when applied to an object should change the sign of each of its data
items.
#include<iostream>
using namespace std;
class space
{
int x;
int y;
int z;
public: void getdata(int a,int b,int c);
void display();
void operator-(); // overload unary minus
};
void space:: getdata(int a,int b, int c)
{
x=a;
y=b;
z=c;
}
void space:: display()
{
std::cout<< x <<" ";
std::cout<< y <<" ";
std::cout<< z <<"n";
}
void space :: operator-()
{
x=-x;
y=-y;
z=-z;
}
int main()
{
space s;
s.getdata(10,-20,30);
cout<<"S :";
s.display();
-s;
cout<<"S :";
s.display();
return 0;
}
C++ program to overload unary minus operator
program adds three additional overloaded operators to the loc class: the –, the =, and the unary ++.
#include <iostream>
using namespace std;
class loc {
int longitude, latitude;
public:
loc() {}
loc(int lg, int lt)
{
longitude = lg;
latitude = lt;
}
void show()
{
cout << longitude << " ";
cout << latitude << "n";
}
loc operator-(loc op2);
loc operator=(loc op2);
loc operator++();
};
loc loc::operator-(loc op2)
{
loc temp;
// notice order of operands
temp.longitude = longitude - op2.longitude;
temp.latitude = latitude - op2.latitude;
return temp;
}
loc loc::operator=(loc op2)
{
longitude = op2.longitude;
latitude = op2.latitude;
return *this;
}
// Overload prefix ++ for loc.
loc loc::operator++()
{
longitude++;
latitude++;
return *this;
}
int main()
{
loc ob1(10, 20),;
loc ob2( 5, 30);
loc ob3(90, 90);
ob1.show();
ob2.show();
++ob1;
ob1.show(); // displays 11 21
ob2 = ++ob1;
ob1.show(); // displays 12 22
ob2.show(); // displays 12 22
ob1 = ob2 = ob3; // multiple assignme
ob1.show(); // displays 90 90
ob2.show(); // displays 90 90
return 0;
}
CREATING PREFIX AND POSTFIX FORMS OF THE INCREMENT AND
DECREMENT OPERATORS
 Standard C++ allows you to explicitly create separate prefix and postfix versions of the
increment or decrement operators.
 To accomplish this, you must define two versions of the operator++( ) function.
 If the ++ precedes its operand, the operator++( ) function is called.
 If the ++ follows its operand, the operator++(int x) is called and x has the value zero
// Prefix increment
type operator++( ) {
// body of prefix operator
}
// Postfix increment
type operator++(int x) {
// body of postfix operator
}
// Prefix decrement
type operator– –( ) {
// body of prefix operator
}
// Postfix decrement
type operator– –(int x) {
// body of postfix operator
}
OVERLOADINGTHE SHORTHAND OPERATORS
 You can overload any of C++'s "shorthand" operators, such as +=, –=, and the like.
 For example, this function overloads += relative to loc:
loc loc::operator+=(loc op2)
{
longitude = op2.longitude + longitude;
latitude = op2.latitude + latitude;
return *this;
}
OPERATOR OVERLOADING RESTRICTIONS
 There are some restrictions that apply to operator overloading.
 You cannot alter the precedence of an operator.
 You cannot change the number of operands that an operator takes. (You can choose to
ignore an operand, however.)
 Except for the function call operator functions cannot have default arguments
OPERATOR OVERLOADING USING A FRIEND FUNCTION
 You can overload an operator for a class by using a nonmember function, which is
usually a friend of the class.
 Since a friend function is not a member of the class, it does not have a this pointer.
 therefore, an overloaded friend operator function is passed the operands explicitly.
 This means that a friend function that overloads a binary operator has two
parameters and a friend function that overloads a unary operator has one
parameter.
 When overloading a binary operator using a friend function, the left operand is
passed in the first parameter and the right operand is passed in the second
parameter
#include <iostream>
using namespace std;
class loc
{
int longitude, latitude;
public:
loc() {}
loc(int lg, int lt)
{
longitude = lg;
latitude = lt;
}
void show()
{
cout << longitude << " ";
cout << latitude << "n";
}
friend loc operator+(loc op1, loc op2);
};
loc operator+(loc op1, loc op2)
{
loc temp;
temp.longitude = op1.longitude + op2.longitude;
temp.latitude = op1.latitude + op2.latitude;
return temp;
}
int main()
{
loc ob1(10, 20), ob2( 5, 30);
ob1.show(); // displays 10 20
ob2.show(); // displays 5 30
ob1 = ob1 + ob2;
ob1.show(); // displays 15 50
return 0;
}
C++ program to overload binary operator using friend
DIFFERENCE
Using Member function
loc operator+(loc op2); //prototype
loc loc::operator+(loc op2) //definition
{
loc temp;
temp.longitude = op2.longitude - longitude;
temp.latitude = op2.latitude-latitude;
return temp;
}
Using friend function
friend loc operator+(loc op1, loc op2); // friend prototype
loc operator+(loc op1, loc op2)
{
loc temp;
temp.longitude = op1.longitude + op2.longitude;
temp.latitude = op1.latitude + op2.latitude;
return temp;
}
USING A FRIEND TO OVERLOAD ++ OR – –
 If you want to use a friend function to overload the increment or decrement operators,
you must pass the operand as a reference parameter.
 This is because friend functions do not have this pointer.
 By specifying the parameter to the friend operator function as a reference parameter
causes any changes made to the parameter inside the function to affect the operand
that generated the call.
 If you want to overload the postfix versions of the increment and decrement operators
using a friend, simply specify a second, dummy integer parameter
// friend, postfix version of ++
friend loc operator++(loc &op, int x);
#include <iostream>
using namespace std;
class loc {
int longitude, latitude;
public:
loc() {}
loc(int lg, int lt)
{
longitude = lg;
latitude = lt;
}
void show()
{
cout << longitude << " ";
cout << latitude << "n";
}
friend loc operator++(loc &op);
friend loc operator--(loc &op);
};
//use a reference parameter.
loc operator++(loc &op)
{
op.longitude++;
op.latitude++;
return op;
}
// Make op-- a friend; use reference.
loc operator--(loc &op)
{
op.longitude--;
op.latitude--;
return op;
}
int main()
{
loc ob1(10, 20), ob2;
ob1.show();
++ob1;
ob1.show(); // displays 11 21
ob2 = ++ob1;
ob2.show(); // displays 12 22
--ob2;
ob2.show(); // displays 11 21
return 0;
}
friend functions to overload the prefix versions of ++ and – – operators relative to the loc class:
FRIEND OPERATOR FUNCTIONS ADD FLEXIBILITY
 In most cases, we get the same results by the use of either a member function or a
friend function.
 There are certain conditions where we would like to use a friend function rather than a
member function.
 For instance, consider the situation where you need to use two different types of
operands for a binary operator, say, one an object and another a built-in type data as
shown in below
 A= B +2; (or A = B * 2;) Where in the above example A and B are objects of the same
class. it will work for a member function
 A = 2 + B; (or A = 2 * B)//invalid it is because the left-hand operand which is responsible for
invoking the member function should be an object of the same class
FRIEND OPERATOR FUNCTIONS ADD FLEXIBILITY
 The solution to the preceding problem is to overload addition using a friend, not a
member function.
 When this is done, both arguments are explicitly passed to the operator function.
 Therefore, to allow both object+integer and integer+object, simply overload the
function twice—one version for each situation.
 Thus, when you overload an operator by using two friend functions, the object may
appear on either the left or right side of the operator.
OVERLOADING NEW AND DELETE
 It is possible to overload new and delete.
 You might choose to do this if you want to use some special allocation method.
 For example, you may want allocation routines that automatically begin using a disk file
as virtual memory when the heap has been exhausted.
// Allocate an object.
void *operator new(size_t size)
{
/* Perform allocation.Throw bad_alloc on
failure. Constructor called automatically. */
return pointer_to_memory;
}
• The type size_t is a defined type capable of containing
the largest single piece of memory that can be allocated.
(size_t is essentially an unsigned integer.)
• The parameter size will contain the number of bytes
needed to hold the object being allocated. This is the
amount of memory that your version of new must
allocate.
• The overloaded new function must return a pointer to
the memory that it allocates, or throw a bad_alloc
exception if an allocation error occurs
OVERLOADING NEW AND DELETE
 The delete function receives a pointer to the region of memory to be freed.
 It then releases the previously allocated memory back to the system.
 When an object is deleted, its destructor is automatically called.
// Delete an object.
void operator delete(void *p)
{
/* Free memory pointed to by p.
Destructor called automatically. */
}
using namespace std;
class loc
{
int longitude, latitude;
public:
loc() {}
loc(int lg, int lt)
{
longitude = lg;
latitude = lt;
}
void show()
{
cout << longitude << " ";
cout << latitude << "n";
}
void *operator new(size_t size);
void operator delete(void *p);
};
// new overloaded relative to loc.
void *loc::operator new(size_t size)
{
void *p;
cout << "In overloaded
new.n";
p = malloc(size);
if(!p)
{
bad_alloc ba;
throw ba;
}
return p;
}
// delete overloaded relative to loc.
void loc::operator delete(void *p)
{
cout << "In overloaded
delete.n";
free(p);
}
int main()
{
loc *p1, *p2;
try
{
p1 = new loc (10, 20);
} catch (bad_alloc xa)
{
cout << "Allocation error for p1.n";
return 1;
}
try
{
p2 = new loc (-10, -20);
} catch (bad_alloc xa)
{
cout << "Allocation error for p2.n";
return 1;
}
p1->show();
p2->show();
delete p1;
delete p2;
return 0;
OVERLOADING NEW AND DELETE FOR ARRAYS
 If you want to be able to allocate arrays of objects using your own allocation system,
you will need to overload new and delete a second time.
 To allocate and free arrays, you must use these forms of new and delete.
// Allocate an array of objects.
void *operator new[](size_t size)
{
/* Perform allocation.Throw bad_alloc on failure.
Constructor for each element called
automatically. */
return pointer_to_memory;
}
// Delete an array of objects.
void operator delete[](void *p)
{
/* Free memory pointed to by p.
Destructor for each element
called automatically.
*/
}
INHERITANCE
INHERITANCE
 Reusability is another important feature of Object Oriented programming
 for instance the re-use of a class that has already been tested, debugged and used many times
can save us the effort of developing and testing the same again.
 Inheritance is one of the cornerstones of OOP because it allows the creation of hierarchical
classifications.
 Using inheritance, you can create a general class that defines common to a set of related items.
 This class may then be inherited by other, more specific classes, each adding only those things
that are unique to the inheriting class.
 The mechanism of deriving a new class from an old one is called 'INHERTTENCE’.
 The inherited class is called a base class or parent class . The class that does the inheriting is
called the derived class.
INHERITANCE
 Further, a derived class can be used as a base class for another derived class.
 The derived class inherits some or all of the features of the base class.
 A class can also inherit properties from more than one class and from more than one
level.
 A derived class also known as(child class) with only one base class, is called single level
inheritance and one with several base classes is called multiple inheritance.
 on the other hand , the features of one class may be inherited by more than one class.
This process is know as hierarchical inheritance.
Types of inheritance
BASE-CLASS ACCESS CONTROL
 When a class inherits another, the members of the base class become members of the
derived class in addition to its own members.
 Class inheritance uses this general form:
class derived-class-name : access base-class-name
{
// body of class
};
• The access status of the base-class
members inside the derived class is
determined by access.
• The base-class access specifier must be
either public, private, or protected.
• If no access specifier is present, the access
specifier is private by default if the derived
class is a class
BASE-CLASS ACCESS CONTROL:THE ACCESS SPECIFIER FOR A BASE
CLASS IS A PUBLIC
 When the access specifier for a base class is public, all public members of the base
become public members of the derived class,
 and all protected members of the base become protected members of the derived
class.
 In all cases, the base's private elements remain private to the base and the private
members of a base class will never become the members of its derived class.
#include <iostream>
using namespace std;
class base
{
int a, b;
public:
void set(int i, int j)
{
a=i;
b=j;
}
void show()
{
cout <<"a:"<<a << "tb: " << b<< "n";
}
};
class derived : public base
{
int k;
public:
setk(int x)
{
k=x;
}
void showk()
{
cout << k << "n";
}
};
int main()
{
derived ob;
ob.set(1, 2); //member of base
ob.show(); //member of base
ob.setk(100);
ob.showk(); //member of derive
return 0;
}
BASE-CLASS ACCESS CONTROL:THE ACCESS SPECIFIER FOR A BASE
CLASS IS A PRIVATE
 When the base class is inherited by using the private access specifier, all public and
protected members of the base class become private members of the derived class.
 // This program won't compile class derived : private base
{
int k;
public:
setk(int x)
{
k=x;
}
void showk()
{
cout << k << "n";
}
};
INHERITANCE AND PROTECTED MEMBERS
 The protected keyword is included in C++ to provide greater flexibility in the inheritance
mechanism.
 When a member of a class is declared as protected, that member is not accessible by other,
nonmember elements of the program.
 access to a protected member is the same as access to a private member—it can be accessed
only by other members of its class.
 The sole exception to this is when a protected member is inherited. In this case, a protected
member differs substantially from a private one.
 If the base class is inherited as public, then the base class’s protected members become
protected members of the derived class and are, therefore, accessible by the derived class.
 By using protected, you can create class members that are private to their class but that can
still be inherited and accessed by a derived class.
#include <iostream>
using namespace std;
class base
{
protected: int a, b; // private to base, but accessible by derived
public:
void set(int i, int j)
{
a=i;
b=j;
}
void show()
{
cout <<"a:"<<a << "tb: " << b<< "n";
}
};
class derived :public base {
int k;
public:
// derived may access base's a and b
setk()
{
k=a*b;
}
void showk()
{
cout << k << "n";
}
};
int main()
{
derived ob;
ob.set(2, 3); // OK, known to derived
ob.show(); // OK, known to derived
ob.setk();
ob.showk();
return 0;
}
BASE-CLASS ACCESS CONTROL:THE ACCESS SPECIFIER FOR A BASE
CLASS IS A PROTECTED
 It is possible to inherit a base class as protected.
 When this is done, all public and protected members of the base class become
protected members of the derived class.
 public members of base, become protected members of derived when it is inherited
using the protected access specifier.
 This means that they will not be accessible inside main( ).
#include <iostream>
using namespace std;
class base {
protected:
int a, b; // private to base, but accessible by derived
public:
void setab(int i, int j)
{
a=i;
b=j;
}
void showab()
{
cout <<"a:"<<a << "tb: " << b<< "n";
}
};
class derived : protected base // Inherit base as protected.
{
int k;
public: // derived may access base's a and b and setab().
void setk()
{
setab(10, 12);
k = a*b;
}
// may access showab() here
void showall()
{
cout << k << " ";
showab();
}
};
int main()
{
derived ob;
ob.setk(); // OK, public member of derived
ob.showall(); // OK, public member of derived of derived
return 0;
VISIBILITY MODES
 we have visibility modes to specify in which mode you are deriving the other class from
the already existing base class.
 Private:
 A base class is privately inherited by a derived class, 'public members' of the base
class become private members of the derived class and therefore the public
members of the base class can be accessed by its objects using the dot operator.
 The result is that we have no member of the base class that is accessible to the
objects of the derived class
VISIBILITY MODES
 Public:
 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.
 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 functions outside these two classes.
THE VISIBILITY MODE TABLE
INHERITING MULTIPLE BASE CLASSES
 A class can inherit the attribute of two or more classes. This is known as multiple
inheritance.
 Multiple inheritance allows users to combine the features of several existing classes as a
starting point for defining new classes.
 It is like a child(subclass) inheriting the physical features of one parent and the intelligence
of another
 The syntax of a derived class with multiple base classes
class D: visibility B_1, visibility B_2,……
{
//body of D class
………..
………..
………..
};
#include <iostream>
using namespace std;
class base1
{
protected:
int x;
public:
void showx()
{
cout << x << "n";
}
};
class base2
{
protected:
int y;
public:
void showy()
{
cout << y << "n";
}
};
class derived: public base1, public base2
{
public:
void set(int i, int j)
{
x=i;
y=j;
}
};
int main()
{
derived ob;
ob.set(10, 20); // provided by derived
ob.showx(); // from base1
ob.showy(); // from base2
return 0;
}
For example, in this short example, derived inherits both base1 and base2.
MULTILEVEL INHERITANCE
 t is not uncommon that a class is derived from another derived
class.
 The class A is a base(super) class for the derived(child) class B ,
which in turn serves as a base class for the derived class C.
 The class B is known as the intermediate base class since it provides
a link for the inheritance between A and C. The chain ABC is known
as the inheritance path
class A
{ // Base class
……….
……….
};
class C: public B
{ // C derived from B
…………
…………
…………
};
class B: public A
{
………… //B derived from A
…………
…………
};
#include<iostream>
using namespace std;
class A
{
public: void displayA()
{
cout<<"Class A"<<endl;
}
};
class B:public A
{
public: void displayB()
{
cout<<"Class B"<<endl;
}
};
class C:public B
{
public: void displayC()
{
cout<<"Class C"<<endl;
}
};
int main()
{
C c;
c.displayA();
c.displayB();
c.displayC();
}
Example:
HYBRID INHERITANCE
 The process of combining more than one type of Inheritance while deriving subclasses
in a program is called a Hybrid Inheritance.
 Multiple Inheritance, Single Inheritance, and Hierarchical Inheritances are combined
together.
#include<iostream>
using namespace std;
class A
{
public: void displayA()
{
cout<<"Class A"<<endl;
}
};
class B:public A
{
public: void displayB()
{
cout<<"Class B"<<endl;
}
};
class C
{
public: void displayC()
{
cout<<"Class C"<<endl;
}
};
class D:public B,public C
{
};
int main()
{
D d;
d.displayA();
d.displayB();
d.displayC();
}
Example:
HIERARCHICAL INHERITANCE
 A single base class can have multiple derived classes, and other subclasses can further inherit
these derived classes, forming a hierarchy of classes.
class base_class
{
//data members
//member functions
};
class derived_class1 : visibility_mode base_class
{
//data members
//member functions
};
class derived_class2 : visibility_mode base_class
{
//data members
//member functions
};
#include<iostream>
using namespace std;
class A
{
public: void displayA()
{
cout<<"Class A"<<endl;
}
};
class B:public A
{
public: void displayB()
{
cout<<"Class B"<<endl;
}
};
class C:public A
{
public: void displayC()
{
cout<<"Class C"<<endl;
}
};
class D:public A
{
};
int main()
{
B b;
b.displayA();
b.displayB();
C c;
c.displayA();
c.displayC();
D d;
d.displayA();
}
CONSTRUCTORS, DESTRUCTORS,AND INHERITANCE
1. when are base-class and derived-class constructors and destructors called?
2. how can parameters be passed to base-class constructors?
WHEN CONSTRUCTORS AND DESTRUCTORS ARE EXECUTED IN
INHERITANCE
 It is possible for a base class, a derived class, or both to contain constructors and/or
destructors.
 It is important to understand the order in which these functions are executed when an
object of a derived class comes into existence and when it goes out of existence.
class base
{
public:
base() { cout << "Constructing basen";
}
~base() { cout << "Destructing
basen"; }
};
class derived: public base
{
public:
derived() { cout << "Constructing derivedn"; }
~derived() { cout << "Destructing derivedn"; }
};
int main()
{
derived ob; // do nothing but construct and destruct ob
return 0;
}
WHEN CONSTRUCTORS AND DESTRUCTORS ARE EXECUTED IN
INHERITANCE
 When an object of a derived class is created, the base class’ constructor will be called first,
followed by the derived class constructor.
 constructors are executed in their order of derivation.
 Because a base class has no knowledge of any derived class, any initialization it needs
to perform is separate from and possibly a prerequisite to any initialization performed
by the derived class.Therefore, it must be executed first.
 When a derived object is destroyed, its destructor is called, followed by the base class'
destructor.
 Destructors are executed in reverse order of derivation.
 Because the base class underlies the derived class, the destruction of the base object
implies the destruction of the derived object. Therefore, the derived destructor must
be called before the object is fully destroyed.
WHEN CONSTRUCTORS AND DESTRUCTORS ARE EXECUTED IN
INHERITANCE
 In cases of multilevel inheritance (that is, where a derived class becomes the base class
for another derived class), the general rule applies:
 Constructors are called in order of derivation, destructors in reverse order
#include <iostream>
using namespace std;
class base
{
public:
base() { cout << "Constructing basen"; }
~base() { cout << "Destructing basen"; }
};
class derived1 : public base
{
public:
derived1() { cout << "Constructing derived1n"; }
~derived1() { cout << "Destructing derived1n"; }
class derived2: public derived1
{
public:
derived2() { cout << "Constructing derived2n"; }
~derived2() { cout << "Destructing derived2n"; }
};
int main()
{
derived2 ob;// construct and destruct ob
return 0;
}
WHEN CONSTRUCTORS AND DESTRUCTORS ARE EXECUTED IN
INHERITANCE
 The same general rule applies in situations involving multiple base classes
#include <iostream>
using namespace std;
class base1
{
public:
base1() { cout << "Constructing base1n"; }
~base1() { cout << "Destructing base1n"; }
};
class base2
{
public:
base2() { cout << "Constructing base2n"; }
~base2() { cout << "Destructing base2n"; }
};
class derived: public base1, public base2 {
public:
derived() { cout << "Constructing derivedn"; }
~derived() { cout << "Destructing derivedn"; }
};
int main()
{
derived ob;
return 0;
}
PASSING PARAMETERS TO BASE-CLASS CONSTRUCTORS
 In cases where only the derived class constructor requires one or more parameters,
you simply use the standard parameterized constructor syntax
 how do you pass arguments to a constructor in a base class?
 The answer is to use an expanded form of the derived class's constructor declaration
that passes along arguments to one or more base-class constructors.
 If any base class contains a constructor with one or more arguments then mandatory
for the derived class to have a constructor and pass the arguments to the base class
constructors.
 Because while applying inheritance usually we create objects using the derived class.
Thus for the derived class to pass arguments to the base class constructor.
PASSING PARAMETERS TO BASE-CLASS CONSTRUCTORS
 When both derived and base classes contain a constructor the base 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 constructor will be executed in the order of inheritance.
 Since the derived class takes the responsibility of supplying initial values to its base
classes we supply the initial values that are required by all the classes together when a
derived class object is declared.
 The constructor of the derived class receives the entire list of values as its arguments
and passes them on to the base constructors in the order in which they are declared in
the derived class.
PASSING PARAMETERS TO BASE-CLASS CONSTRUCTORS
 The base constructors are called and executed before executing the statements in the
body of the derived constructor.
 The general form of this expanded derived-class constructor declaration :
derived-constructor(arg-list) : base1(arg-list),base2(arg-list),...baseN(arg-list)
{
// body of derived constructor
}
• Here, base1 through baseN are the names of the base classes inherited by the derived
class.
• Notice that a colon separates the derived class constructor declaration from the base-
class specifications and that the base-class specifications are separated from each other by
commas, in the case of multiple base classes.
#include <iostream>
using namespace std;
class base
{
protected:
int i;
public:
base(int x)
{
i=x;
cout << "Constructing basen";
}
~base()
{
cout << "Destructing basen";
}
};
class derived: public base
{
int j;
public:
derived(int x, int y): base(y)
{
j=x;
cout << "Constructing
derivedn";
}
~derived()
{
cout << "Destructing derivedn";
}
void show()
{
cout << i << " " << j << "n";
}
};
int main()
{
derived ob(3, 4);
ob.show(); // displays 4
return 0;
}
PASSING PARAMETERS TO BASE-CLASS CONSTRUCTORS
 any parameters required by the base class are passed to it in the base class' argument
list specified after the colon.
 example that uses multiple base classes
#include<iostream>
using namespace std;
class alpha
{
int x;
public:
alpha(int i)
{
x=i;
cout<<"Alpha Initializedn";
}
void show_x()
{
cout<<"n x="<<x;
}
};
class beta
{
float y;
public:
beta(float j)
{
y=j;
cout<<"Beta Initialized n";
}
void show_y()
{
cout<<"n y="<<y;
}
};
class gamma:public beta,public alpha
{
int m,n,c,d;
public:
gamma(int a,float b,int c,int d):alpha(a),beta(b)
{
m=c;
n=d;
cout<<"n gamma initialized n";
}
void show_mn()
{
cout<<"n m="<<m;
cout<<"n n="<<n;
}
};
int main()
{
gamma g(5,7.65,30,100);
g.show_x();
g.show_y();
g.show_mn();
return 0;
Develop a C++ program using Constructor in Derived classes to initialize alpha, beta and gamma and display corresponding values.
PASSING PARAMETERS TO BASE-CLASS CONSTRUCTORS
 It is important to understand that arguments to a base-class constructor are passed via
arguments to the derived class' constructor.
 Therefore, even if a derived class’ constructor does not use any arguments, it will still
need to declare one if the base class requires it.
 In this situation, the arguments passed to the derived class are simply passed along to
the base.
 For example, in this program, the derived class' constructor takes no arguments, but
base1( ) and base2( )
#include <iostream>
using namespace std;
class base1 {
protected:
int i;
public:
base1(int x)
{
i=x;
cout << "Constructing base1n";
}
~base1()
{
cout << "Destructing base1n";
}
};
class base2
{
protected:
int k;
public:
base2(int x)
{
k=x;
cout << "Constructing base2n";
}
~base2()
{
cout << "Destructing base2n";
}
};
class derived: public base1, public base2
{
public:
derived(int x, int y): base1(x), base2(y)
{
cout << "Constructing derivedn";
}
~derived()
{
cout << "Destructing derivedn";
}
void show()
{
cout << i << " " << k << "n";
}
};
int main()
{
derived ob(3, 4);
ob.show(); // displays 3 4
return 0;
GRANTING ACCESS IN THE DERIVED CLASS
 When a base class is inherited as private, all public and protected members of that class
become private members of the derived class
 However, in certain circumstances, you may want to restore one or more inherited
members to their original access specification.
 For example, you might want to grant certain public members of the base class public
status in the derived class even though the base class is inherited as private.
 In Standard C++, you have two ways to accomplish this. First, you can use a using
statement, which is the preferred way.
 The using statement is designed primarily to support namespaces.
 The second way to restore an inherited member's access specification is to employ
an access declaration within the derived class
GRANTING ACCESS IN THE DERIVED CLASS
 An access declaration takes this general form:
base-class::member;
class base
{
public:
int j; // public in base
};
// Inherit base as private.
class derived: private base
{
public:
// here is access declaration
base::j; // make j public again
.
.
.
};
▪ Because the base is inherited as private by derived,
the public member j is made a private member of
derived
▪ base::j;
▪ as the access declaration under derived's public
heading, j is restored to its public status
▪ The access declaration is put under the appropriate
access heading in the derived class declaration.
▪ Notice that no type declaration is required (or,
indeed, allowed) in an access declaration
GRANTING ACCESS IN THE DERIVED CLASS
 you cannot use an access declaration to raise or lower a member’s access status.
 For example, a member declared as private in a base class cannot be made public by a
derived class.
 Note:
 While Standard C++ still supports access declarations, they are deprecated. This means that
they are allowed for now, but they might not be supported in the future. Instead, the
standard suggests achieving the same effect by applying the using keyword
MULTIPLE INHERITANCE AND AMBIGUITY
 An element of ambiguity can be introduced into a C++ program when multiple base
classes are inherited.
 when a function with the same inheritance appears in more than one base class
// This program contains an error and will not compile.
#include <iostream>
using namespace std;
class base
{
public:
int i;
};
// derived1 inherits base.
class derived1 : public base
{
public:
int j;
};
// derived2 inherits base.
class derived2 : public base
{
public:
int k;
};
class derived3 : public derived1, public derived2
{
public:
int sum;
};
int main()
{
derived3 ob;
ob.i = 10; // this is ambiguous, which i???
ob.j = 20;
ob.k = 30;
ob.sum = ob.i + ob.j + ob.k; // i ambiguous here, too
cout << ob.i << " // also ambiguous, which i?
cout << ob.j << " ";" << ob.k << " ";
cout << ob.sum;
return 0;
}
MULTIPLE INHERITANCE AND AMBIGUITY
 In the program both derived1 and derived2 inherit base. However, derived3 inherits both
derived1 and derived2.
 This means that there are two copies of base present in an object of type derived3.
Therefore, in an expression like
 ob.i = 10; which i is being referred to,?
 the one in derived1 or the one in derived2? Since there are two copies of base present in
object ob, there are two ob.i.As you can see, the statement is inherently ambiguous.
 What is the remedy for this type of problem?
 There are two ways to remedy the preceding program.
1. The first is to apply the scope resolution operator to i and manually select one i.
2. virtual base classes
1.APPLY THE SCOPE RESOLUTION OPERATOR TO RESOLVE
AMBIGUITY IN MULTIPLE INHERITANCE
int main()
{
derived3 ob;
ob.derived1::i = 10; // this is ambiguous, which i???
ob.j = 20;
ob.k = 30;
ob.sum = ob.derived1::i + ob.j + ob.k;// i ambiguous here,
t cout << ob.derived1::i <<endl;// also ambiguous, which i?
cout << ob.j <<endl << ob.k <<endl;
cout << "sum="<<ob.sum;
return 0;
}
• because the :: was applied, the
program has manually selected
derived1's version of base.
• this solution raises a deeper issue:
• What if only one copy of base is
required? Is there some way to
prevent two copies from being
included in derived3?
The solution is achieved using virtual base classes.
2.VIRTUAL BASE CLASSES
 When two or more objects are derived from a common base class, you can prevent
multiple copies of the base class from being present in an object derived from those
classes, by declaring the base class as virtual when it is inherited.
 To do this, you precede the name of the base class with the keyword virtual when it is
inherited.
class base
{
public:
int i;
};
// derived2 inherits base.
class derived2 : virtual public base
{
public:
int k;
};
// derived1 inherits base.
class derived1 :virtual public base
{
public:
int j;
};
2.VIRTUAL BASE CLASSES
 Now that both derived1 and derived2 have inherited base as virtual, any multiple
inheritance involving them will cause only one copy of base to be present.
 Therefore, in derived3, there is only one copy of base and ob.i = 10 is perfectly valid
and unambiguous.
 The difference between a normal base class and a virtual base class one becomes
evident only when an object inherits the base class more than once.
 If virtual base classes are used, then only one base class is present in the object.
 Otherwise, multiple copies will be found.

More Related Content

PPTX
Lecture 5, c++(complete reference,herbet sheidt)chapter-15
PPTX
Operator overloading2
PDF
Ch-4-Operator Overloading.pdf
PPTX
Object Oriented Programming using C++: Ch08 Operator Overloading.pptx
PPTX
Mca 2nd sem u-4 operator overloading
PDF
Object Oriented Programming using C++ - Part 3
PPTX
Bca 2nd sem u-4 operator overloading
PDF
Operator overloading
Lecture 5, c++(complete reference,herbet sheidt)chapter-15
Operator overloading2
Ch-4-Operator Overloading.pdf
Object Oriented Programming using C++: Ch08 Operator Overloading.pptx
Mca 2nd sem u-4 operator overloading
Object Oriented Programming using C++ - Part 3
Bca 2nd sem u-4 operator overloading
Operator overloading

Similar to 22 scheme OOPs with C++ BCS306B_module3.pdf (20)

PPT
Lec 26.27-operator overloading
PPTX
operator overloading
PDF
Polymorphism and Type Conversion.pdf pot
PDF
Basics _of_Operator Overloading_Somesh_Kumar_SSTC
PPTX
PPT
Lec 28 - operator overloading
PPTX
Operator overloading
PDF
C++ aptitude
PDF
overloading in C++
PPTX
operator overloading
PPTX
3. Polymorphism.pptx
PPTX
Operator overloading
PPT
Operator Overloading
PPT
3d7b7 session4 c++
PDF
C++aptitude questions and answers
PPTX
operator overloading & type conversion in cpp
PPTX
operator overloading & type conversion in cpp over view || c++
PPTX
Unary operator overloading
PPT
Polymorphism and function overloading_new.ppt
PPTX
Functions in C++ programming language.pptx
Lec 26.27-operator overloading
operator overloading
Polymorphism and Type Conversion.pdf pot
Basics _of_Operator Overloading_Somesh_Kumar_SSTC
Lec 28 - operator overloading
Operator overloading
C++ aptitude
overloading in C++
operator overloading
3. Polymorphism.pptx
Operator overloading
Operator Overloading
3d7b7 session4 c++
C++aptitude questions and answers
operator overloading & type conversion in cpp
operator overloading & type conversion in cpp over view || c++
Unary operator overloading
Polymorphism and function overloading_new.ppt
Functions in C++ programming language.pptx
Ad

Recently uploaded (20)

PDF
Unit I ESSENTIAL OF DIGITAL MARKETING.pdf
PDF
BIO-INSPIRED HORMONAL MODULATION AND ADAPTIVE ORCHESTRATION IN S-AI-GPT
PPTX
additive manufacturing of ss316l using mig welding
PDF
PREDICTION OF DIABETES FROM ELECTRONIC HEALTH RECORDS
PPTX
Sustainable Sites - Green Building Construction
PPTX
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
PPTX
CYBER-CRIMES AND SECURITY A guide to understanding
PPTX
Artificial Intelligence
PPT
Total quality management ppt for engineering students
PDF
Well-logging-methods_new................
PPTX
UNIT 4 Total Quality Management .pptx
PDF
Categorization of Factors Affecting Classification Algorithms Selection
PPTX
UNIT-1 - COAL BASED THERMAL POWER PLANTS
PDF
Automation-in-Manufacturing-Chapter-Introduction.pdf
PPT
Mechanical Engineering MATERIALS Selection
PDF
R24 SURVEYING LAB MANUAL for civil enggi
PPTX
Construction Project Organization Group 2.pptx
PDF
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
PDF
A SYSTEMATIC REVIEW OF APPLICATIONS IN FRAUD DETECTION
PPT
Project quality management in manufacturing
Unit I ESSENTIAL OF DIGITAL MARKETING.pdf
BIO-INSPIRED HORMONAL MODULATION AND ADAPTIVE ORCHESTRATION IN S-AI-GPT
additive manufacturing of ss316l using mig welding
PREDICTION OF DIABETES FROM ELECTRONIC HEALTH RECORDS
Sustainable Sites - Green Building Construction
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
CYBER-CRIMES AND SECURITY A guide to understanding
Artificial Intelligence
Total quality management ppt for engineering students
Well-logging-methods_new................
UNIT 4 Total Quality Management .pptx
Categorization of Factors Affecting Classification Algorithms Selection
UNIT-1 - COAL BASED THERMAL POWER PLANTS
Automation-in-Manufacturing-Chapter-Introduction.pdf
Mechanical Engineering MATERIALS Selection
R24 SURVEYING LAB MANUAL for civil enggi
Construction Project Organization Group 2.pptx
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
A SYSTEMATIC REVIEW OF APPLICATIONS IN FRAUD DETECTION
Project quality management in manufacturing
Ad

22 scheme OOPs with C++ BCS306B_module3.pdf

  • 2. INTRODUCTION  In C++, you can overload most operators so that they perform special operations relative to classes that you create.  For example, a class that maintains a stack might overload + to perform a push operation and – to perform a pop.  When an operator is overloaded, none of its original meanings are lost.  It allows the full integration of new class types into the programming environment.  After overloading the appropriate operators, you can use objects in expressions just the same way that you use C++'s built-in data types.  An operator function defines the operations that the overloaded operator will perform relative to the class upon which it will work.  An operator function is created using the keyword operator.  Operator functions can be either members or nonmembers of a class. Nonmember operator functions are almost always friend functions of the class
  • 3. INTRODUCTION  We can overload all the C++ operators except the following:  Class members access operator (. , .*)  Scope resolution operator (: :)  Size operator(sizeof)  Condition operator (? :)
  • 4. CREATING A MEMBER OPERATOR FUNCTION ( OPERATOR OVERLOADING)  To define an additional task to an operator, we must specify what it means in relation to the class to which the operator is applied.  This is done with the help of a special function called operator function, which describes the task  A member operator function(Operator Overloading) takes this general form: returntype class-name::operator#(arg-list) { // operations } • operator functions return an object of the class they operate on, but returntype can be any valid type. • The # is a placeholder. When you create an operator function, substitute the operator for the #
  • 5. CREATING A MEMBER OPERATOR FUNCTION (OPERATOR OVERLOADING)  operator functions are declared in. the class using prototypes as follows:-  vector is a data type of class and may represent both magnitude and direction or a series of points called elements • vector operator + (vector); /./ vector addition • vector operator-( ); //unary minus • friend vector operator + (vuelor, vector); // vector add • friend vector operator -(vector); // unary minus • vector operator - ( vector &a); // substraction • int operator = =(vector); //comparision • friend int operator = =(vector ,vrctor); // comparision
  • 6. CREATING A MEMBER OPERATOR FUNCTION (OPERATOR OVERLOADING)  The process of overloading involves the following steps. 1. Create a class that defines the data type used in the overloading operation. 2. Declare the operator function operator op() in the public part of the class 3. It may be either a member function or a friend function. 4. Define the operator function to implement the required operations Overloaded operator functions can be invoked by expressions such as • op x or x op; for unary operators • x op y; for binary operators. • operator op(x); for unary operator using friend function • operator op(x,y); for binary operator using friend function
  • 7. #include <iostream> using namespace std; class loc { int longitude, latitude; public: loc() {} loc(int lg, int lt) { longitude = lg; latitude = lt; } void show() { cout << longitude << " "; cout << latitude << "n"; } loc operator+(loc op2); }; loc loc::operator+(loc op2) { loc temp; temp.longitude = op2.longitude + longitude; temp.latitude = op2.latitude + latitude; return temp; } int main() { loc ob1(10, 20), ob2( 5, 30); ob1.show(); // displays 10 20 ob2.show(); // displays 5 30 ob1 = ob1 + ob2; ob1.show(); // displays 15 50 return 0; } C++ program to overload binary operator
  • 8. CREATING A MEMBER OPERATOR FUNCTION (OPERATOR OVERLOADING)  operator+( ) has only one parameter even though it overloads the binary + operator.  The reason that operator+( ) takes only one parameter is that the operand on the left side of the + is passed implicitly to the function through the this pointer.  The operand on the right is passed in the parameter op2.  When binary operators are overloaded, it is the object on the left that generates the call to the operator function.  As mentioned, it is common for an overloaded operator function to return an object of the class it operates upon.  By doing so, it allows the operator to be used in larger expressions.
  • 9. C++ overloading binary operators(adding two complex numbers) # include <iostream> using namespace std; class complex { float x; // real part float y; // imaginary part public : complex() { } // constructor 1 complex(float real, float imag) // constructor 2 { x = real; y = imag; } complex operator + (complex); void display(); }; complex complex :: operator+(complex c) { complex temp; //temporary temp.x = x + c.x; // these are temp.y = y + c.y; // statement for float additions return(temp); void complex :: display() { cout << x << " + j" << y << "n"; } int main() { complex c1, c2, c3; c1 = complex (2.5, 3.5); c2 = complex (1.6, 2.7); c3 = c1 + c2; cout << "c1 = "; c1.display(); cout << "c2 = "; c2.display(); cout << "nc3 = "; c3.display(); return 0; }
  • 10. OVERLOADING UNARY OPERATORS(USING MEMBER FUNCTION)  Let us consider unary minus operator.  A minus operator used when as a unary, takes just only one operand.  We know that this operator changes the sign of an operand when applied to a basic one operand.  We will see here how to overload this operator so that it can be applied to an object in much the same way as is applied to an int or float variable.  The minus unary when applied to an object should change the sign of each of its data items.
  • 11. #include<iostream> using namespace std; class space { int x; int y; int z; public: void getdata(int a,int b,int c); void display(); void operator-(); // overload unary minus }; void space:: getdata(int a,int b, int c) { x=a; y=b; z=c; } void space:: display() { std::cout<< x <<" "; std::cout<< y <<" "; std::cout<< z <<"n"; } void space :: operator-() { x=-x; y=-y; z=-z; } int main() { space s; s.getdata(10,-20,30); cout<<"S :"; s.display(); -s; cout<<"S :"; s.display(); return 0; } C++ program to overload unary minus operator
  • 12. program adds three additional overloaded operators to the loc class: the –, the =, and the unary ++. #include <iostream> using namespace std; class loc { int longitude, latitude; public: loc() {} loc(int lg, int lt) { longitude = lg; latitude = lt; } void show() { cout << longitude << " "; cout << latitude << "n"; } loc operator-(loc op2); loc operator=(loc op2); loc operator++(); }; loc loc::operator-(loc op2) { loc temp; // notice order of operands temp.longitude = longitude - op2.longitude; temp.latitude = latitude - op2.latitude; return temp; } loc loc::operator=(loc op2) { longitude = op2.longitude; latitude = op2.latitude; return *this; } // Overload prefix ++ for loc. loc loc::operator++() { longitude++; latitude++; return *this; } int main() { loc ob1(10, 20),; loc ob2( 5, 30); loc ob3(90, 90); ob1.show(); ob2.show(); ++ob1; ob1.show(); // displays 11 21 ob2 = ++ob1; ob1.show(); // displays 12 22 ob2.show(); // displays 12 22 ob1 = ob2 = ob3; // multiple assignme ob1.show(); // displays 90 90 ob2.show(); // displays 90 90 return 0; }
  • 13. CREATING PREFIX AND POSTFIX FORMS OF THE INCREMENT AND DECREMENT OPERATORS  Standard C++ allows you to explicitly create separate prefix and postfix versions of the increment or decrement operators.  To accomplish this, you must define two versions of the operator++( ) function.  If the ++ precedes its operand, the operator++( ) function is called.  If the ++ follows its operand, the operator++(int x) is called and x has the value zero // Prefix increment type operator++( ) { // body of prefix operator } // Postfix increment type operator++(int x) { // body of postfix operator } // Prefix decrement type operator– –( ) { // body of prefix operator } // Postfix decrement type operator– –(int x) { // body of postfix operator }
  • 14. OVERLOADINGTHE SHORTHAND OPERATORS  You can overload any of C++'s "shorthand" operators, such as +=, –=, and the like.  For example, this function overloads += relative to loc: loc loc::operator+=(loc op2) { longitude = op2.longitude + longitude; latitude = op2.latitude + latitude; return *this; }
  • 15. OPERATOR OVERLOADING RESTRICTIONS  There are some restrictions that apply to operator overloading.  You cannot alter the precedence of an operator.  You cannot change the number of operands that an operator takes. (You can choose to ignore an operand, however.)  Except for the function call operator functions cannot have default arguments
  • 16. OPERATOR OVERLOADING USING A FRIEND FUNCTION  You can overload an operator for a class by using a nonmember function, which is usually a friend of the class.  Since a friend function is not a member of the class, it does not have a this pointer.  therefore, an overloaded friend operator function is passed the operands explicitly.  This means that a friend function that overloads a binary operator has two parameters and a friend function that overloads a unary operator has one parameter.  When overloading a binary operator using a friend function, the left operand is passed in the first parameter and the right operand is passed in the second parameter
  • 17. #include <iostream> using namespace std; class loc { int longitude, latitude; public: loc() {} loc(int lg, int lt) { longitude = lg; latitude = lt; } void show() { cout << longitude << " "; cout << latitude << "n"; } friend loc operator+(loc op1, loc op2); }; loc operator+(loc op1, loc op2) { loc temp; temp.longitude = op1.longitude + op2.longitude; temp.latitude = op1.latitude + op2.latitude; return temp; } int main() { loc ob1(10, 20), ob2( 5, 30); ob1.show(); // displays 10 20 ob2.show(); // displays 5 30 ob1 = ob1 + ob2; ob1.show(); // displays 15 50 return 0; } C++ program to overload binary operator using friend
  • 18. DIFFERENCE Using Member function loc operator+(loc op2); //prototype loc loc::operator+(loc op2) //definition { loc temp; temp.longitude = op2.longitude - longitude; temp.latitude = op2.latitude-latitude; return temp; } Using friend function friend loc operator+(loc op1, loc op2); // friend prototype loc operator+(loc op1, loc op2) { loc temp; temp.longitude = op1.longitude + op2.longitude; temp.latitude = op1.latitude + op2.latitude; return temp; }
  • 19. USING A FRIEND TO OVERLOAD ++ OR – –  If you want to use a friend function to overload the increment or decrement operators, you must pass the operand as a reference parameter.  This is because friend functions do not have this pointer.  By specifying the parameter to the friend operator function as a reference parameter causes any changes made to the parameter inside the function to affect the operand that generated the call.  If you want to overload the postfix versions of the increment and decrement operators using a friend, simply specify a second, dummy integer parameter // friend, postfix version of ++ friend loc operator++(loc &op, int x);
  • 20. #include <iostream> using namespace std; class loc { int longitude, latitude; public: loc() {} loc(int lg, int lt) { longitude = lg; latitude = lt; } void show() { cout << longitude << " "; cout << latitude << "n"; } friend loc operator++(loc &op); friend loc operator--(loc &op); }; //use a reference parameter. loc operator++(loc &op) { op.longitude++; op.latitude++; return op; } // Make op-- a friend; use reference. loc operator--(loc &op) { op.longitude--; op.latitude--; return op; } int main() { loc ob1(10, 20), ob2; ob1.show(); ++ob1; ob1.show(); // displays 11 21 ob2 = ++ob1; ob2.show(); // displays 12 22 --ob2; ob2.show(); // displays 11 21 return 0; } friend functions to overload the prefix versions of ++ and – – operators relative to the loc class:
  • 21. FRIEND OPERATOR FUNCTIONS ADD FLEXIBILITY  In most cases, we get the same results by the use of either a member function or a friend function.  There are certain conditions where we would like to use a friend function rather than a member function.  For instance, consider the situation where you need to use two different types of operands for a binary operator, say, one an object and another a built-in type data as shown in below  A= B +2; (or A = B * 2;) Where in the above example A and B are objects of the same class. it will work for a member function  A = 2 + B; (or A = 2 * B)//invalid it is because the left-hand operand which is responsible for invoking the member function should be an object of the same class
  • 22. FRIEND OPERATOR FUNCTIONS ADD FLEXIBILITY  The solution to the preceding problem is to overload addition using a friend, not a member function.  When this is done, both arguments are explicitly passed to the operator function.  Therefore, to allow both object+integer and integer+object, simply overload the function twice—one version for each situation.  Thus, when you overload an operator by using two friend functions, the object may appear on either the left or right side of the operator.
  • 23. OVERLOADING NEW AND DELETE  It is possible to overload new and delete.  You might choose to do this if you want to use some special allocation method.  For example, you may want allocation routines that automatically begin using a disk file as virtual memory when the heap has been exhausted. // Allocate an object. void *operator new(size_t size) { /* Perform allocation.Throw bad_alloc on failure. Constructor called automatically. */ return pointer_to_memory; } • The type size_t is a defined type capable of containing the largest single piece of memory that can be allocated. (size_t is essentially an unsigned integer.) • The parameter size will contain the number of bytes needed to hold the object being allocated. This is the amount of memory that your version of new must allocate. • The overloaded new function must return a pointer to the memory that it allocates, or throw a bad_alloc exception if an allocation error occurs
  • 24. OVERLOADING NEW AND DELETE  The delete function receives a pointer to the region of memory to be freed.  It then releases the previously allocated memory back to the system.  When an object is deleted, its destructor is automatically called. // Delete an object. void operator delete(void *p) { /* Free memory pointed to by p. Destructor called automatically. */ }
  • 25. using namespace std; class loc { int longitude, latitude; public: loc() {} loc(int lg, int lt) { longitude = lg; latitude = lt; } void show() { cout << longitude << " "; cout << latitude << "n"; } void *operator new(size_t size); void operator delete(void *p); }; // new overloaded relative to loc. void *loc::operator new(size_t size) { void *p; cout << "In overloaded new.n"; p = malloc(size); if(!p) { bad_alloc ba; throw ba; } return p; } // delete overloaded relative to loc. void loc::operator delete(void *p) { cout << "In overloaded delete.n"; free(p); } int main() { loc *p1, *p2; try { p1 = new loc (10, 20); } catch (bad_alloc xa) { cout << "Allocation error for p1.n"; return 1; } try { p2 = new loc (-10, -20); } catch (bad_alloc xa) { cout << "Allocation error for p2.n"; return 1; } p1->show(); p2->show(); delete p1; delete p2; return 0;
  • 26. OVERLOADING NEW AND DELETE FOR ARRAYS  If you want to be able to allocate arrays of objects using your own allocation system, you will need to overload new and delete a second time.  To allocate and free arrays, you must use these forms of new and delete. // Allocate an array of objects. void *operator new[](size_t size) { /* Perform allocation.Throw bad_alloc on failure. Constructor for each element called automatically. */ return pointer_to_memory; } // Delete an array of objects. void operator delete[](void *p) { /* Free memory pointed to by p. Destructor for each element called automatically. */ }
  • 28. INHERITANCE  Reusability is another important feature of Object Oriented programming  for instance the re-use of a class that has already been tested, debugged and used many times can save us the effort of developing and testing the same again.  Inheritance is one of the cornerstones of OOP because it allows the creation of hierarchical classifications.  Using inheritance, you can create a general class that defines common to a set of related items.  This class may then be inherited by other, more specific classes, each adding only those things that are unique to the inheriting class.  The mechanism of deriving a new class from an old one is called 'INHERTTENCE’.  The inherited class is called a base class or parent class . The class that does the inheriting is called the derived class.
  • 29. INHERITANCE  Further, a derived class can be used as a base class for another derived class.  The derived class inherits some or all of the features of the base class.  A class can also inherit properties from more than one class and from more than one level.  A derived class also known as(child class) with only one base class, is called single level inheritance and one with several base classes is called multiple inheritance.  on the other hand , the features of one class may be inherited by more than one class. This process is know as hierarchical inheritance.
  • 31. BASE-CLASS ACCESS CONTROL  When a class inherits another, the members of the base class become members of the derived class in addition to its own members.  Class inheritance uses this general form: class derived-class-name : access base-class-name { // body of class }; • The access status of the base-class members inside the derived class is determined by access. • The base-class access specifier must be either public, private, or protected. • If no access specifier is present, the access specifier is private by default if the derived class is a class
  • 32. BASE-CLASS ACCESS CONTROL:THE ACCESS SPECIFIER FOR A BASE CLASS IS A PUBLIC  When the access specifier for a base class is public, all public members of the base become public members of the derived class,  and all protected members of the base become protected members of the derived class.  In all cases, the base's private elements remain private to the base and the private members of a base class will never become the members of its derived class.
  • 33. #include <iostream> using namespace std; class base { int a, b; public: void set(int i, int j) { a=i; b=j; } void show() { cout <<"a:"<<a << "tb: " << b<< "n"; } }; class derived : public base { int k; public: setk(int x) { k=x; } void showk() { cout << k << "n"; } }; int main() { derived ob; ob.set(1, 2); //member of base ob.show(); //member of base ob.setk(100); ob.showk(); //member of derive return 0; }
  • 34. BASE-CLASS ACCESS CONTROL:THE ACCESS SPECIFIER FOR A BASE CLASS IS A PRIVATE  When the base class is inherited by using the private access specifier, all public and protected members of the base class become private members of the derived class.  // This program won't compile class derived : private base { int k; public: setk(int x) { k=x; } void showk() { cout << k << "n"; } };
  • 35. INHERITANCE AND PROTECTED MEMBERS  The protected keyword is included in C++ to provide greater flexibility in the inheritance mechanism.  When a member of a class is declared as protected, that member is not accessible by other, nonmember elements of the program.  access to a protected member is the same as access to a private member—it can be accessed only by other members of its class.  The sole exception to this is when a protected member is inherited. In this case, a protected member differs substantially from a private one.  If the base class is inherited as public, then the base class’s protected members become protected members of the derived class and are, therefore, accessible by the derived class.  By using protected, you can create class members that are private to their class but that can still be inherited and accessed by a derived class.
  • 36. #include <iostream> using namespace std; class base { protected: int a, b; // private to base, but accessible by derived public: void set(int i, int j) { a=i; b=j; } void show() { cout <<"a:"<<a << "tb: " << b<< "n"; } }; class derived :public base { int k; public: // derived may access base's a and b setk() { k=a*b; } void showk() { cout << k << "n"; } }; int main() { derived ob; ob.set(2, 3); // OK, known to derived ob.show(); // OK, known to derived ob.setk(); ob.showk(); return 0; }
  • 37. BASE-CLASS ACCESS CONTROL:THE ACCESS SPECIFIER FOR A BASE CLASS IS A PROTECTED  It is possible to inherit a base class as protected.  When this is done, all public and protected members of the base class become protected members of the derived class.  public members of base, become protected members of derived when it is inherited using the protected access specifier.  This means that they will not be accessible inside main( ).
  • 38. #include <iostream> using namespace std; class base { protected: int a, b; // private to base, but accessible by derived public: void setab(int i, int j) { a=i; b=j; } void showab() { cout <<"a:"<<a << "tb: " << b<< "n"; } }; class derived : protected base // Inherit base as protected. { int k; public: // derived may access base's a and b and setab(). void setk() { setab(10, 12); k = a*b; } // may access showab() here void showall() { cout << k << " "; showab(); } }; int main() { derived ob; ob.setk(); // OK, public member of derived ob.showall(); // OK, public member of derived of derived return 0;
  • 39. VISIBILITY MODES  we have visibility modes to specify in which mode you are deriving the other class from the already existing base class.  Private:  A base class is privately inherited by a derived class, 'public members' of the base class become private members of the derived class and therefore the public members of the base class can be accessed by its objects using the dot operator.  The result is that we have no member of the base class that is accessible to the objects of the derived class
  • 40. VISIBILITY MODES  Public:  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.  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 functions outside these two classes.
  • 42. INHERITING MULTIPLE BASE CLASSES  A class can inherit the attribute of two or more classes. This is known as multiple inheritance.  Multiple inheritance allows users to combine the features of several existing classes as a starting point for defining new classes.  It is like a child(subclass) inheriting the physical features of one parent and the intelligence of another  The syntax of a derived class with multiple base classes class D: visibility B_1, visibility B_2,…… { //body of D class ……….. ……….. ……….. };
  • 43. #include <iostream> using namespace std; class base1 { protected: int x; public: void showx() { cout << x << "n"; } }; class base2 { protected: int y; public: void showy() { cout << y << "n"; } }; class derived: public base1, public base2 { public: void set(int i, int j) { x=i; y=j; } }; int main() { derived ob; ob.set(10, 20); // provided by derived ob.showx(); // from base1 ob.showy(); // from base2 return 0; } For example, in this short example, derived inherits both base1 and base2.
  • 44. MULTILEVEL INHERITANCE  t is not uncommon that a class is derived from another derived class.  The class A is a base(super) class for the derived(child) class B , which in turn serves as a base class for the derived class C.  The class B is known as the intermediate base class since it provides a link for the inheritance between A and C. The chain ABC is known as the inheritance path class A { // Base class ………. ………. }; class C: public B { // C derived from B ………… ………… ………… }; class B: public A { ………… //B derived from A ………… ………… };
  • 45. #include<iostream> using namespace std; class A { public: void displayA() { cout<<"Class A"<<endl; } }; class B:public A { public: void displayB() { cout<<"Class B"<<endl; } }; class C:public B { public: void displayC() { cout<<"Class C"<<endl; } }; int main() { C c; c.displayA(); c.displayB(); c.displayC(); } Example:
  • 46. HYBRID INHERITANCE  The process of combining more than one type of Inheritance while deriving subclasses in a program is called a Hybrid Inheritance.  Multiple Inheritance, Single Inheritance, and Hierarchical Inheritances are combined together.
  • 47. #include<iostream> using namespace std; class A { public: void displayA() { cout<<"Class A"<<endl; } }; class B:public A { public: void displayB() { cout<<"Class B"<<endl; } }; class C { public: void displayC() { cout<<"Class C"<<endl; } }; class D:public B,public C { }; int main() { D d; d.displayA(); d.displayB(); d.displayC(); } Example:
  • 48. HIERARCHICAL INHERITANCE  A single base class can have multiple derived classes, and other subclasses can further inherit these derived classes, forming a hierarchy of classes. class base_class { //data members //member functions }; class derived_class1 : visibility_mode base_class { //data members //member functions }; class derived_class2 : visibility_mode base_class { //data members //member functions };
  • 49. #include<iostream> using namespace std; class A { public: void displayA() { cout<<"Class A"<<endl; } }; class B:public A { public: void displayB() { cout<<"Class B"<<endl; } }; class C:public A { public: void displayC() { cout<<"Class C"<<endl; } }; class D:public A { }; int main() { B b; b.displayA(); b.displayB(); C c; c.displayA(); c.displayC(); D d; d.displayA(); }
  • 50. CONSTRUCTORS, DESTRUCTORS,AND INHERITANCE 1. when are base-class and derived-class constructors and destructors called? 2. how can parameters be passed to base-class constructors?
  • 51. WHEN CONSTRUCTORS AND DESTRUCTORS ARE EXECUTED IN INHERITANCE  It is possible for a base class, a derived class, or both to contain constructors and/or destructors.  It is important to understand the order in which these functions are executed when an object of a derived class comes into existence and when it goes out of existence. class base { public: base() { cout << "Constructing basen"; } ~base() { cout << "Destructing basen"; } }; class derived: public base { public: derived() { cout << "Constructing derivedn"; } ~derived() { cout << "Destructing derivedn"; } }; int main() { derived ob; // do nothing but construct and destruct ob return 0; }
  • 52. WHEN CONSTRUCTORS AND DESTRUCTORS ARE EXECUTED IN INHERITANCE  When an object of a derived class is created, the base class’ constructor will be called first, followed by the derived class constructor.  constructors are executed in their order of derivation.  Because a base class has no knowledge of any derived class, any initialization it needs to perform is separate from and possibly a prerequisite to any initialization performed by the derived class.Therefore, it must be executed first.  When a derived object is destroyed, its destructor is called, followed by the base class' destructor.  Destructors are executed in reverse order of derivation.  Because the base class underlies the derived class, the destruction of the base object implies the destruction of the derived object. Therefore, the derived destructor must be called before the object is fully destroyed.
  • 53. WHEN CONSTRUCTORS AND DESTRUCTORS ARE EXECUTED IN INHERITANCE  In cases of multilevel inheritance (that is, where a derived class becomes the base class for another derived class), the general rule applies:  Constructors are called in order of derivation, destructors in reverse order #include <iostream> using namespace std; class base { public: base() { cout << "Constructing basen"; } ~base() { cout << "Destructing basen"; } }; class derived1 : public base { public: derived1() { cout << "Constructing derived1n"; } ~derived1() { cout << "Destructing derived1n"; } class derived2: public derived1 { public: derived2() { cout << "Constructing derived2n"; } ~derived2() { cout << "Destructing derived2n"; } }; int main() { derived2 ob;// construct and destruct ob return 0; }
  • 54. WHEN CONSTRUCTORS AND DESTRUCTORS ARE EXECUTED IN INHERITANCE  The same general rule applies in situations involving multiple base classes #include <iostream> using namespace std; class base1 { public: base1() { cout << "Constructing base1n"; } ~base1() { cout << "Destructing base1n"; } }; class base2 { public: base2() { cout << "Constructing base2n"; } ~base2() { cout << "Destructing base2n"; } }; class derived: public base1, public base2 { public: derived() { cout << "Constructing derivedn"; } ~derived() { cout << "Destructing derivedn"; } }; int main() { derived ob; return 0; }
  • 55. PASSING PARAMETERS TO BASE-CLASS CONSTRUCTORS  In cases where only the derived class constructor requires one or more parameters, you simply use the standard parameterized constructor syntax  how do you pass arguments to a constructor in a base class?  The answer is to use an expanded form of the derived class's constructor declaration that passes along arguments to one or more base-class constructors.  If any base class contains a constructor with one or more arguments then mandatory for the derived class to have a constructor and pass the arguments to the base class constructors.  Because while applying inheritance usually we create objects using the derived class. Thus for the derived class to pass arguments to the base class constructor.
  • 56. PASSING PARAMETERS TO BASE-CLASS CONSTRUCTORS  When both derived and base classes contain a constructor the base 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 constructor will be executed in the order of inheritance.  Since the derived class takes the responsibility of supplying initial values to its base classes we supply the initial values that are required by all the classes together when a derived class object is declared.  The constructor of the derived class receives the entire list of values as its arguments and passes them on to the base constructors in the order in which they are declared in the derived class.
  • 57. PASSING PARAMETERS TO BASE-CLASS CONSTRUCTORS  The base constructors are called and executed before executing the statements in the body of the derived constructor.  The general form of this expanded derived-class constructor declaration : derived-constructor(arg-list) : base1(arg-list),base2(arg-list),...baseN(arg-list) { // body of derived constructor } • Here, base1 through baseN are the names of the base classes inherited by the derived class. • Notice that a colon separates the derived class constructor declaration from the base- class specifications and that the base-class specifications are separated from each other by commas, in the case of multiple base classes.
  • 58. #include <iostream> using namespace std; class base { protected: int i; public: base(int x) { i=x; cout << "Constructing basen"; } ~base() { cout << "Destructing basen"; } }; class derived: public base { int j; public: derived(int x, int y): base(y) { j=x; cout << "Constructing derivedn"; } ~derived() { cout << "Destructing derivedn"; } void show() { cout << i << " " << j << "n"; } }; int main() { derived ob(3, 4); ob.show(); // displays 4 return 0; }
  • 59. PASSING PARAMETERS TO BASE-CLASS CONSTRUCTORS  any parameters required by the base class are passed to it in the base class' argument list specified after the colon.  example that uses multiple base classes
  • 60. #include<iostream> using namespace std; class alpha { int x; public: alpha(int i) { x=i; cout<<"Alpha Initializedn"; } void show_x() { cout<<"n x="<<x; } }; class beta { float y; public: beta(float j) { y=j; cout<<"Beta Initialized n"; } void show_y() { cout<<"n y="<<y; } }; class gamma:public beta,public alpha { int m,n,c,d; public: gamma(int a,float b,int c,int d):alpha(a),beta(b) { m=c; n=d; cout<<"n gamma initialized n"; } void show_mn() { cout<<"n m="<<m; cout<<"n n="<<n; } }; int main() { gamma g(5,7.65,30,100); g.show_x(); g.show_y(); g.show_mn(); return 0; Develop a C++ program using Constructor in Derived classes to initialize alpha, beta and gamma and display corresponding values.
  • 61. PASSING PARAMETERS TO BASE-CLASS CONSTRUCTORS  It is important to understand that arguments to a base-class constructor are passed via arguments to the derived class' constructor.  Therefore, even if a derived class’ constructor does not use any arguments, it will still need to declare one if the base class requires it.  In this situation, the arguments passed to the derived class are simply passed along to the base.  For example, in this program, the derived class' constructor takes no arguments, but base1( ) and base2( )
  • 62. #include <iostream> using namespace std; class base1 { protected: int i; public: base1(int x) { i=x; cout << "Constructing base1n"; } ~base1() { cout << "Destructing base1n"; } }; class base2 { protected: int k; public: base2(int x) { k=x; cout << "Constructing base2n"; } ~base2() { cout << "Destructing base2n"; } }; class derived: public base1, public base2 { public: derived(int x, int y): base1(x), base2(y) { cout << "Constructing derivedn"; } ~derived() { cout << "Destructing derivedn"; } void show() { cout << i << " " << k << "n"; } }; int main() { derived ob(3, 4); ob.show(); // displays 3 4 return 0;
  • 63. GRANTING ACCESS IN THE DERIVED CLASS  When a base class is inherited as private, all public and protected members of that class become private members of the derived class  However, in certain circumstances, you may want to restore one or more inherited members to their original access specification.  For example, you might want to grant certain public members of the base class public status in the derived class even though the base class is inherited as private.  In Standard C++, you have two ways to accomplish this. First, you can use a using statement, which is the preferred way.  The using statement is designed primarily to support namespaces.  The second way to restore an inherited member's access specification is to employ an access declaration within the derived class
  • 64. GRANTING ACCESS IN THE DERIVED CLASS  An access declaration takes this general form: base-class::member; class base { public: int j; // public in base }; // Inherit base as private. class derived: private base { public: // here is access declaration base::j; // make j public again . . . }; ▪ Because the base is inherited as private by derived, the public member j is made a private member of derived ▪ base::j; ▪ as the access declaration under derived's public heading, j is restored to its public status ▪ The access declaration is put under the appropriate access heading in the derived class declaration. ▪ Notice that no type declaration is required (or, indeed, allowed) in an access declaration
  • 65. GRANTING ACCESS IN THE DERIVED CLASS  you cannot use an access declaration to raise or lower a member’s access status.  For example, a member declared as private in a base class cannot be made public by a derived class.  Note:  While Standard C++ still supports access declarations, they are deprecated. This means that they are allowed for now, but they might not be supported in the future. Instead, the standard suggests achieving the same effect by applying the using keyword
  • 66. MULTIPLE INHERITANCE AND AMBIGUITY  An element of ambiguity can be introduced into a C++ program when multiple base classes are inherited.  when a function with the same inheritance appears in more than one base class
  • 67. // This program contains an error and will not compile. #include <iostream> using namespace std; class base { public: int i; }; // derived1 inherits base. class derived1 : public base { public: int j; }; // derived2 inherits base. class derived2 : public base { public: int k; }; class derived3 : public derived1, public derived2 { public: int sum; }; int main() { derived3 ob; ob.i = 10; // this is ambiguous, which i??? ob.j = 20; ob.k = 30; ob.sum = ob.i + ob.j + ob.k; // i ambiguous here, too cout << ob.i << " // also ambiguous, which i? cout << ob.j << " ";" << ob.k << " "; cout << ob.sum; return 0; }
  • 68. MULTIPLE INHERITANCE AND AMBIGUITY  In the program both derived1 and derived2 inherit base. However, derived3 inherits both derived1 and derived2.  This means that there are two copies of base present in an object of type derived3. Therefore, in an expression like  ob.i = 10; which i is being referred to,?  the one in derived1 or the one in derived2? Since there are two copies of base present in object ob, there are two ob.i.As you can see, the statement is inherently ambiguous.  What is the remedy for this type of problem?  There are two ways to remedy the preceding program. 1. The first is to apply the scope resolution operator to i and manually select one i. 2. virtual base classes
  • 69. 1.APPLY THE SCOPE RESOLUTION OPERATOR TO RESOLVE AMBIGUITY IN MULTIPLE INHERITANCE int main() { derived3 ob; ob.derived1::i = 10; // this is ambiguous, which i??? ob.j = 20; ob.k = 30; ob.sum = ob.derived1::i + ob.j + ob.k;// i ambiguous here, t cout << ob.derived1::i <<endl;// also ambiguous, which i? cout << ob.j <<endl << ob.k <<endl; cout << "sum="<<ob.sum; return 0; } • because the :: was applied, the program has manually selected derived1's version of base. • this solution raises a deeper issue: • What if only one copy of base is required? Is there some way to prevent two copies from being included in derived3? The solution is achieved using virtual base classes.
  • 70. 2.VIRTUAL BASE CLASSES  When two or more objects are derived from a common base class, you can prevent multiple copies of the base class from being present in an object derived from those classes, by declaring the base class as virtual when it is inherited.  To do this, you precede the name of the base class with the keyword virtual when it is inherited. class base { public: int i; }; // derived2 inherits base. class derived2 : virtual public base { public: int k; }; // derived1 inherits base. class derived1 :virtual public base { public: int j; };
  • 71. 2.VIRTUAL BASE CLASSES  Now that both derived1 and derived2 have inherited base as virtual, any multiple inheritance involving them will cause only one copy of base to be present.  Therefore, in derived3, there is only one copy of base and ob.i = 10 is perfectly valid and unambiguous.  The difference between a normal base class and a virtual base class one becomes evident only when an object inherits the base class more than once.  If virtual base classes are used, then only one base class is present in the object.  Otherwise, multiple copies will be found.