OOPS THROUGH C++ 1 Dr. Chandra Sekhar Sanaboina Assistant Professor Department of Computer Science and Engineering University College of Engineering Kakinada Jawaharlal Nehru Technological University Kakinada Website: https://drcs.info Youtube Link: https://www.youtube.com/watch?v=nPjHraTbPeY&list=PLT1ngltOnlJiHbzVvjkU8VzQt9oam8ji4
UNIT – III OPERATOR OVERLOADING AND TYPE CONVERSION & INHERITANCE 2
AGENDA • Operator Overloading • The keyword Operator • Overloading Unary Operator • Operator Return Type • Overloading Assignment Operator (=) • Rules for Overloading Operators • Inheritance • Reusability • Types of Inheritance • Virtual Base Classes • Object as a Class Member • Abstract Classes • Advantages of Inheritance • Disadvantages of Inheritance 3
OPERATOR OVERLOADING • Introduction • Operator overloading is an important concept in C++ • In C++, we can make operators to work for user defined classes • This means C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading • It is polymorphism in which an operator is overloaded to give user defined meaning to it • Overloaded operator is used to perform operation on user-defined data type • For example '+' operator can be overloaded to perform addition on various data types, like for Integer, String(concatenation) etc., 4
OPERATOR OVERLOADING CONTD… • Important technique that has enhanced the power of extendibility of C++ • C++ tries to make the user defined data types behave in the same way as the built-in data types • It is a type of polymorphism in which an operator is overloaded to give the user defined meaning of it 5
DIFFERENCE BETWEEN OPERATOR FUNCTIONS AND NORMAL FUNCTIONS? • Operator functions are same as normal functions • The only differences are • name of an operator function is always operator keyword followed by symbol of operator • operator functions are called when the corresponding operator is used 6
OPERATOR OVERLOADING CONTD… • Almost any operator can be overloaded in C++ • However there are few operator which can not be overloaded • Operator that are not overloaded are • Scope Resolution Operator (::) • sizeof • Member Selector (.) • Member Pointer Selector (*) • Ternary Operator (?:) 7
OPERATOR OVERLOADING CONTD… Syntax for Operator Overloading Returntype Classname :: operator OperatorSymbol (argumentlist) { Function Body } 8
IMPLEMENTING OPERATOR OVERLOADING • Operator overloading can be done by implementing a function which can be : • Member Function • Non-Member Function • Friend Function • Operator overloading function can be a member function if the Left operand is an Object of that class • If the Left operand is different, then Operator overloading function must be a non-member function • Operator overloading function can be made friend function if it needs access to the private and protected members of class 9
RESTRICTIONS ON OPERATOR OVERLOADING IN C++ • Following are some restrictions to be kept in mind while implementing operator overloading • Precedence and Associativity of an operator cannot be changed • Arity (numbers of Operands) cannot be changed. Unary operator remains unary, binary remains binary etc • No new operators can be created, only existing operators can be overloaded • Cannot redefine the meaning of a procedure (i.e., we cannot change how integers are added) 10
OVERLOADING ARITHMETIC OPERATORS IN C++ • Arithmetic operator are most commonly used operator in C++ • Almost all arithmetic operator can be overloaded to perform arithmetic operation on user-defined data type 11
OVERLOADING ARITHMETIC OPERATORS IN C++ #include <iostream> #include <conio.h> using namespace std; class Time { int h,m,s; public: Time() { h=0, m=0; s=0; } void setTime(); void show() { cout<<h<<":"<<m<<":"<<s; } //overloading '+' operator Time operator +(Time); }; void time::setTime() { cout << "n Enter the hour(0-11) "; cin >> h; cout << "n Enter the minute(0-59) "; cin >> m; cout << "n Enter the second(0-59) "; cin >> s; } Time Time::operator+(Time t1) //operator function { Time t; int a,b; a = s+t1.s; t.s = a%60; b = (a/60)+m+t1.m; t.m = b%60; t.h = (b/60)+h+t1.h; t.h = t.h%12; return t; } void main() { Time t1,t2,t3; cout << "n Enter the first time "; t1.setTime(); cout << "n Enter the second time "; t2.setTime(); t3 = t1 + t2; //adding of two time object using '+' operator //t3=t1.add(t2); - this is how the compiler treats the above cout << "n First time "; t1.show(); cout << "n Second time "; t2.show(); cout << "n Sum of times "; t3.show(); getch(); } 12
OVERLOADING RELATIONAL OPERATORS IN C++ • You can also overload relational operators like ==, !=, >=, <= etc., to compare two object of any class 13
OVERLOADING RELATIONAL OPERATORS IN C++ class Time { int hr, min, sec; public: // default constructor Time() { hr=0, min=0; sec=0; } // overloaded constructor Time(int h, int m, int s) { hr=h, min=m; sec=s; } //overloading '==' operator friend bool operator==(Time &t1, Time &t2); }; bool operator== (Time &t1, Time &t2) { return ( t1.hr == t2.hr && t1.min == t2.min && t1.sec == t2.sec ); } void main() { Time t1(3,15,45); Time t2(4,15,45); if(t1 == t2) { cout << "Both the time values are equal"; } else { cout << "Both the time values are not equal"; } } 14
FRIEND FUNCTIONS • A friend function of a class is defined outside that class scope • Friend function has the right to access all private and protected members of the class • Even though the prototypes for friend functions appear in the class definition, friends are not member functions 15
WHY FRIEND FUNCTION • Special case when private members of the class need to be accessed directly without using object of that class • Used in Operator Overloading 16
FRIEND FUNCTION EXAMPLE #include<iostream> using namespace std; class Demo{ private: int len; public: Demo() { len=0; } Demo(int l) { len=l; } friend void increase(Demo &d); void print(); }; void Demo::print(){ cout<<"Length is "<<len<<endl; } void increase(Demo &d) { d.len=d.len+10; } int main(){ Demo d(5); d.print(); increase(d); d.print();} 17
OVERLOADING UNARY OPERATORS • Unary operators operate on only one operand • The increment operator ++ and decrement operator -- are examples of unary operators 18
OVERLOADING UNARY OPERATOR // Overload ++ when used as prefix #include <iostream> using namespace std; class Count { private: int value; public: // Constructor to initialize count to 5 Count() : value(5) {} // Overload ++ when used as prefix void operator ++ () { ++value; } void display() { cout << "Count: " << value << endl; } }; int main() { Count count1; // Call the "void operator ++ ()" function ++count1; count1.display(); return 0; } 19
OVERLOADING UNARY OPERATORS • For Postfix Operation: void operator ++ (int) { value++; } 20
OVERLOADING UNARY OPERATOR WITH RETURN VALUE #include <iostream> using namespace std; class Count { private: int value; public : // Constructor to initialize count to 5 Count() : value(5) {} // Overload ++ when used as prefix Count operator ++ () { Count temp; // Here, value is the value attribute of the calling object temp.value = ++value; return temp; } / //Overload ++ when used as postfix Count operator ++ (int) { Count temp; // Here, value is the value attribute of the calling object temp.value = value++; return temp; } void display() { cout << "Count: " << value << endl; } }; int main() { Count count1, result; // Call the "Count operator ++ ()" function result = ++count1; result.display(); // Call the "Count operator ++ (int)" function result = count1++; result.display(); return 0; } 21
OVERLOADING ASSIGNMENT OPERATOR • The assignment operator (operator=) is used to copy values from one object to another already existing object 22
OVERLOADING ASSIGNMENT OPERATOR #include <iostream> using namespace std; class Distance { private: int feet; // 0 to infinite int inches; // 0 to 12 public: // required constructors Distance() { feet = 0; inches = 0; } Distance(int f, int i) { feet = f; inches = i; } void operator = (const Distance &D ) { feet = D.feet; inches = D.inches; } // method to display distance void displayDistance() { cout << "F: " << feet << " I:" << inches << endl; } }; int main() { Distance D1(11, 10), D2(5, 11); cout << "First Distance : "; D1.displayDistance(); cout << "Second Distance :"; D2.displayDistance(); // use assignment operator D1 = D2; cout << "First Distance :"; D1.displayDistance(); return 0; } 23
RULES FOR OPERATOR OVERLOADING • Only built-in operators can be overloaded. If some operators are not present in C++, we cannot overload them. • The arity of the operators cannot be changed • The precedence of the operators remains same • We cannot overload operators for built-in data types. At least one user defined data types must be there. • The assignment “=”, subscript “[]”, function call “()” and arrow operator “->” these operators must be defined as member functions, not the friend functions. • Some operators like assignment “=”, address “&” and comma “,” are by default overloaded. 24
INHERITANCE 25
INHERITANCE • Introduction: • The capability of a class to derive properties and characteristics from another class is called Inheritance • Inheritance is one of the most important feature of Object Oriented Programming • Sub Class: The class that inherits properties from another class is called Sub class or Derived Class • Super Class: The class whose properties are inherited by sub class is called Base Class or Super class 26
WHY INHERITANCE? • Reusability • Consider a group of vehicles Bus, Car and Truck. • We need to create classes for Bus, Car and Truck • Assume the methods fuelAmount(), capacity(), applyBrakes() will be same for all of the three classes • If we create these classes avoiding inheritance then we have to write all of these functions in each of the three classes 27
WHY INHERITANCE CONTD… • You can clearly see that above process results in duplication of same code 3 times • Disadvantages: • Increase in error rate and data redundancy • To avoid this type of situation, inheritance is used • If we create a class Vehicle and write these three functions in it and inherit the rest of the classes from the vehicle class, then we can simply avoid the duplication of data and increase re-usability 28
IMPLEMENTING INHERITANCE IN C++ • For creating a sub-class which is inherited from the base class we have to follow the below syntax: class subclass_name : access_specifier base_class_name { //subclass body }; • subclass_name is the name of the sub class • access_mode is the mode in which you want to inherit this sub class • base_class_name is the name of the base class from which you want to inherit the sub class 29
INHERITANCE EXAMPLE #include <bits/stdc++.h> using namespace std; //Base class class Parent { public: int id_p; }; // Sub class inheriting from Base Class(Parent) class Child : public Parent { public: int id_c; }; //main function int main() { Child obj1; // An object of class child has all data members // and member functions of class parent obj1.id_c = 7; obj1.id_p = 91; cout << "Child id is " << obj1.id_c << endl; cout << "Parent id is " << obj1.id_p << endl; return 0; } 30
MODES OF INHERITANCE 31
MODES OF INHERITANCE • Public mode: • If we derive a sub class from a public base class • Then the public member of the base class will become public in the derived class and protected members of the base class will become protected in derived class • Protected mode: • If we derive a sub class from a Protected base class • Then both public member and protected members of the base class will become protected in derived class • Private mode: • If we derive a sub class from a Private base class • Then both public member and protected members of the base class will become Private in derived class • Note: Private members of a base class cannot be directly accessed in derived class, while protected members can be directly accessed 32
MODES OF INHERITANCE CONTD… class A { public: int x; protected: int y; private: int z; }; class B : public A { // x is public // y is protected // z is not accessible from B }; class C : protected A { // x is protected // y is protected // z is not accessible from C }; class D : private A // 'private' is default for classes { // x is private // y is private // z is not accessible from D }; 33
MODES OF INHERITANCE CONTD… 34
TYPES OF INHERITANCE 35
TYPES OF INHERITANCE • Single Inheritance • Multiple Inheritance • Multilevel Inheritance • Hierarchical Inheritance • Hybrid Inheritance • Multipath Inheritance 36
SINGLE INHERITANCE 37
SINGLE INHERITANCE • Single Inheritance: • In single inheritance, a class is allowed to inherit from only one class • One sub class is inherited by one base class only 38
SINGLE INHERITANCE SYNTAX class subclass_name : access_mode base_class1 { //body of subclass }; 39
SINGLE INHERITANCE 40
SINGLE INHERITANCE EXAMPLE #include <iostream> using namespace std; // base class class Vehicle { public: Vehicle() { cout << "This is a Vehicle" << endl; } }; // sub class derived from a single base classes class Car: public Vehicle{ }; // main function int main() { // creating object of sub class will // invoke the constructor of base classes Car obj; return 0; } 41
MULTIPLE INHERITANCE 42
MULTIPLE INHERITANCE • Multiple Inheritance: • Multiple Inheritance is a feature of C++ where a class can inherit from more than one classes • i.e one sub class is inherited from more than one base classes 43
MULTIPLE INHERITANCE 44
MULTIPLE INHERITANCE SYNTAX class subclass_name : access_mode base_class1, access_mode base_class2, .... { //body of subclass }; 45
MULTIPLE INHERITANCE EXAMPLE #include <iostream> using namespace std; // first base class class Vehicle { public: Vehicle() { cout << "This is a Vehicle" << endl; } }; // second base class class FourWheeler { public: FourWheeler() { cout << "This is a 4 wheeler Vehicle" << endl; } }; // sub class derived from two base classes class Car: public Vehicle, public FourWheeler { }; // main function int main() { // creating object of sub class will // invoke the constructor of base classes Car obj; return 0; } 46
MULTILEVEL INHERITANCE 47
MULTILEVEL INHERITANCE • Multilevel Inheritance: • In this type of inheritance, a derived class is created from another derived class 48
MULTILEVEL INHERITANCE 49
MULTILEVEL INHERITANCE EXAMPLE #include <iostream> using namespace std; // base class class Vehicle { public: Vehicle() { cout << "This is a Vehicle" << endl; } }; // first sub_class derived from class vehicle class fourWheeler: public Vehicle { public: fourWheeler() { cout<<"Objects with 4 wheels are vehicles"<<endl; } }; // sub class derived from the derived base class fourWheeler class Car: public fourWheeler{ public: Car() { cout<<"Car has 4 Wheels"<<endl; } }; // main function int main() { //creating object of sub class will //invoke the constructor of base classes Car obj; return 0; } 50
HIERARCHICAL INHERITANCE 51
HIERARCHICAL INHERITANCE • Hierarchical Inheritance: • In this type of inheritance, more than one sub class is inherited from a single base class • i.e. more than one derived class is created from a single base class. 52
HIERARCHICAL INHERITANCE 53
HIERARCHICAL INHERITANCE EXAMPLE #include <iostream> using namespace std; // base class class Vehicle { public: Vehicle() { cout << "This is a Vehicle" << endl; } }; // first sub class class Car: public Vehicle { }; // second sub class class Bus: public Vehicle { }; // main function int main() { // creating object of sub class will // invoke the constructor of base class Car obj1; Bus obj2; return 0; } 54
HYBRID INHERITANCE 55
HYBRID INHERITANCE • Hybrid (Virtual) Inheritance: • Hybrid Inheritance is implemented by combining more than one type of inheritance • For example: Combining Hierarchical inheritance and Multiple Inheritance 56
HYBRID INHERITANCE 57
HYBRID INHERITANCE EXAMPLE // C++ program for Hybrid Inheritance #include <iostream> using namespace std; // base class class Vehicle { public: Vehicle() { cout << "This is a Vehicle" << endl; } }; //base class class Fare { public: Fare() { cout<<"Fare of Vehiclen"; } }; // first sub class class Car: public Vehicle { }; // second sub class class Bus: public Vehicle, public Fare { }; // main function int main() { // creating object of sub class will // invoke the constructor of base class Bus obj2; return 0; } 58
MULTIPATH INHERITANCE 59
MULTIPATH INHERITANCE • Multipath Inheritance: • A special case of hybrid inheritance • A derived class with two base classes and these two base classes have one common base class is called multipath inheritance • An ambiguity can arise in this type of inheritance • Example: • Combining Hierarchical inheritance and Multiple Inheritance 60
MULTIPATH INHERITANCE EXAMPLE // C++ program demonstrating ambiguity in Multipath Inheritance #include <conio.h> #include <iostream.h> class ClassA { public: int a; }; class ClassB : public ClassA { public: int b; }; class ClassC : public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; void main() { ClassD obj; // obj.a = 10; //Statement 1, Error // obj.a = 100; //Statement 2, Error obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout << "n A from ClassB : " << obj.ClassB::a; cout << "n A from ClassC : " << obj.ClassC::a; cout << "n B : " << obj.b; cout << "n C : " << obj.c; cout << "n D : " << obj.d; } 61
AMBIGUITY IN MULTIPATH INHERITANCE 62
AMBIGUITY IN MULTIPATH INHERITANCE • In the above example, both ClassB & ClassC inherit ClassA, they both have single copy of ClassA • However ClassD inherit both ClassB & ClassC, therefore ClassD have two copies of ClassA, one from ClassB and another from ClassC • If we need to access the data member a of ClassA through the object of ClassD, we must specify the path from which a will be accessed, whether it is from ClassB or ClassC, bco’z compiler can’t differentiate between two copies of ClassA in ClassD 63
HOW TO AVOID AMBIGUITY IN MULTIPATH INHERITANCE? • There are 2 ways to avoid this ambiguity: • Avoiding ambiguity using scope resolution operator: • Using scope resolution operator we can manually specify the path from which data member a will be accessed, as shown in statement 3 and 4, in the above example. • Example: • obj.ClassB::a = 10; //Statement 3 • obj.ClassC::a = 100; //Statement 4 • Avoiding ambiguity using virtual base class: • Explanation using a programming Example 64
SOLUTION 1 FOR RESOLVING AMBIGUITY – USING SCOPE RESOLUTION OPERATOR // C++ program demonstrating ambiguity in Multipath Inheritance #include <conio.h> #include <iostream.h> class ClassA { public: int a; }; class ClassB : public ClassA { public: int b; }; class ClassC : public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; void main() { ClassD obj; obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout << "n A from ClassB : " << obj.ClassB::a; cout << "n A from ClassC : " << obj.ClassC::a; cout << "n B : " << obj.b; cout << "n C : " << obj.c; cout << "n D : " << obj.d; } 65
SOLUTION 2 FOR RESOLVING AMBIGUITY – USING VIRTUAL BASE CLASSES #include<iostream.h> #include<conio.h> class ClassA { public: int a; }; class ClassB : virtual public ClassA { public: int b; }; class ClassC : virtual public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; void main() { ClassD obj; obj.a = 10; //Statement 3 obj.a = 100; //Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout<< "n A : "<< obj.a; cout<< "n B : "<< obj.b; cout<< "n C : "<< obj.c; cout<< "n D : "<< obj.d; } Note: According to the above example, ClassD has only one copy of ClassA, therefore, statement 4 will overwrite the value of a, given at statement 3. 66
VIRTUAL BASE CLASSES 67
VIRTUAL BASE CLASSES • Virtual base classes are used in virtual inheritance • It is to prevent multiple “instances” of a given class appearing in an inheritance hierarchy when using multiple inheritances 68
NEED FOR VIRTUAL BASE CLASSES • Consider the situation where we have one class A • This class is A is inherited by two other classes B and C • Both these class are inherited into another in a new class D as shown in figure • The data members/function of class A are inherited twice to class D - One through class B and second through class C • When any data / function member of class A is accessed by an object of class D, ambiguity arises as to which data/function member would be called? (One inherited through B or the other inherited through C) • This confuses compiler and it displays error 69
AMBIGUITY RAISED DUE TO INHERITANCE #include <iostream> using namespace std; class A { public: void show() { cout << "Hello form A n"; } }; class B : public A { }; class C : public A { }; class D : public B, public C { }; int main() { D object; object.show(); } Output: Error 70
HOW TO RESOLVE THE AMBIGUITY? • Virtual base classes offer a way to save space and avoid ambiguities in class hierarchies that use multiple inheritances • When a base class is specified as a virtual base, it can act as an indirect base more than once without duplication of its data members • A single copy of its data members is shared by all the base classes that use virtual base • To resolve this ambiguity when class A is inherited in both class B and class C, it is declared as virtual base class by placing a keyword virtual • Syntax 1: class B : virtual public A { }; • Syntax 2: class C : virtual public A { }; • Now only one copy of data/function member will be copied to class C and class B and class A becomes the virtual base class • Note: virtual can be placed before or after public keyword 71
SOLUTION FOR AMBIGUITY – VIRTUAL BASE CLASSES ##include <iostream> using namespace std; class A { public: int a; A() // constructor { a = 10; } }; class B : public virtual A { }; class C : public virtual A { }; class D : public B, public C { }; int main() { D object; // object creation of class d cout << "a = " << object.a << endl; return 0; } 72
ABSTRACT CLASSES 73
ABSTRACT CLASSES • Abstract Class is a class which contains atleast one Pure Virtual function in it • Abstract classes are used to provide an Interface for its sub classes • Classes inheriting an Abstract Class must provide definition to the pure virtual function, otherwise they will also become abstract class 74
CHARACTERISTICS OF ABSTRACT CLASS • Abstract class cannot be instantiated, but pointers and references of Abstract class type can be created • Abstract class can have normal functions and variables along with a pure virtual function • Abstract classes are mainly used for Upcasting, so that its derived classes can use its interface • Classes inheriting an Abstract Class must implement all pure virtual functions, or else they will become Abstract too 75
UPCASTING IN C++ 76
UPCASTING IN C++ • Upcasting is using the Super class's reference or pointer to refer to a Sub class's object or • The act of converting a Sub class's reference or pointer into its Super class's reference or pointer is called Upcasting 77
UPCASTING EXAMPLE class Super { int x; public: void funBase() { cout << "Super function"; } }; class Sub:public Super { int y; }; int main() { Super* ptr; // Super class pointer Sub obj; ptr = &obj; Super &ref; // Super class's reference ref=obj; } 78
VIRTUAL FUNCTIONS 79
VIRTUAL FUNCTIONS IN C++ • A virtual function is a member function in the base class that are expected to redefine in derived classes • Functions are declared with a virtual keyword in base class • Basically, a virtual function is used in the base class in order to ensure that the function is overridden • This especially applies to cases where a pointer of base class points to an object of a derived class • They are mainly used to achieve Runtime polymorphism • The resolving of function call is done at Run-time 80
VIRTUAL FUNCTIONS CONTD… • Rules for Virtual Functions • Virtual functions cannot be static • A virtual function can be a friend function of another class • Virtual functions should be accessed using pointer or reference of base class type to achieve run time polymorphism • The prototype of virtual functions should be the same in the base as well as derived class • They are always defined in the base class and overridden in a derived class. It is not mandatory for the derived class to override (or re-define the virtual function), in that case, the base class version of the function is used • A class may have virtual destructor but it cannot have a virtual constructor 81
PURE VIRTUAL FUNCTIONS 82
PURE VIRTUAL FUNCTIONS IN C++ • Pure virtual Functions are virtual functions with no definition • They start with virtual keyword and ends with = 0 • Syntax: • virtual void f() = 0; 83
PURE VIRTUAL FUNCTIONS EXAMPLE class Base { public: virtual void show() = 0; // Pure Virtual Function }; class Derived:public Base { public: void show() { cout << "Implementation of Virtual Function in Derived classn"; } }; int main() { Base obj; //Compile Time Error Base *b; Derived d; b = &d; b->show(); } Note: In the above example Base class is abstract, with pure virtual show() function, hence we cannot create object of base class. 84
WHY CAN'T WE CREATE OBJECT OF AN ABSTRACT CLASS? • When we create a pure virtual function in Abstract class, we reserve a slot for a function in the VTABLE but doesn't put any address in that slot • Hence the VTABLE will be incomplete • As the VTABLE for Abstract class is incomplete, hence the compiler will not let the creation of object for such class and will display an errror message whenever you try to do so 85
PURE VIRTUAL DEFINITIONS 86
PURE VIRTUAL DEFINITIONS • Pure Virtual functions can be given a small definition in the Abstract class, which you want all the derived classes to have • Still you cannot create object of Abstract class • Also, the Pure Virtual function must be defined outside the class definition • If you will define it inside the class definition, complier will give an error • Inline pure virtual definition is Illegal 87
PURE VIRTUAL DEFINITION EXAMPLE // Abstract base class class Base { public: virtual void show() = 0; //Pure Virtual Function }; void Base :: show() //Pure Virtual definition { cout << "Pure Virtual definitionn"; } class Derived:public Base { public: void show() { cout << "Implementation of Virtual Function in Derived classn"; } }; int main() { Base *b; Derived d; b = &d; b->show(); } 88
ADVANTAGES AND DISADVANTAGES 89
ADVANTAGES OF INHERITANCE • Inheritance promotes reusability: • When a class inherits or derives another class, it can access all the functionality of inherited class • Reusability enhanced reliability: • The base class code will be already tested and debugged • As the existing code is reused, it leads to less development and maintenance costs • Inheritance makes the sub classes follow a standard interface • Inheritance helps to reduce code redundancy and supports code extensibility • Inheritance facilitates creation of class libraries 90
DISADVANTAGES OF INHERITANCE • Inherited functions work slower than normal function as there is indirection • Improper use of inheritance may lead to wrong solutions • Often, data members in the base class are left unused which may lead to memory wastage • Inheritance increases the coupling between base class and derived class. A change in base class will affect all the child classes. 91
FUNCTIONS THAT ARE NEVER INHERITED • Constructors and Destructors are never inherited and hence never overrided • Assignment Operator (=) is never inherited (It can be overloaded but can never be inherited) 92
THE END 93

Object Oriented Programming using C++ - Part 3

  • 1.
    OOPS THROUGH C++ 1 Dr.Chandra Sekhar Sanaboina Assistant Professor Department of Computer Science and Engineering University College of Engineering Kakinada Jawaharlal Nehru Technological University Kakinada Website: https://drcs.info Youtube Link: https://www.youtube.com/watch?v=nPjHraTbPeY&list=PLT1ngltOnlJiHbzVvjkU8VzQt9oam8ji4
  • 2.
    UNIT – III OPERATOROVERLOADING AND TYPE CONVERSION & INHERITANCE 2
  • 3.
    AGENDA • Operator Overloading •The keyword Operator • Overloading Unary Operator • Operator Return Type • Overloading Assignment Operator (=) • Rules for Overloading Operators • Inheritance • Reusability • Types of Inheritance • Virtual Base Classes • Object as a Class Member • Abstract Classes • Advantages of Inheritance • Disadvantages of Inheritance 3
  • 4.
    OPERATOR OVERLOADING • Introduction •Operator overloading is an important concept in C++ • In C++, we can make operators to work for user defined classes • This means C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading • It is polymorphism in which an operator is overloaded to give user defined meaning to it • Overloaded operator is used to perform operation on user-defined data type • For example '+' operator can be overloaded to perform addition on various data types, like for Integer, String(concatenation) etc., 4
  • 5.
    OPERATOR OVERLOADING CONTD… •Important technique that has enhanced the power of extendibility of C++ • C++ tries to make the user defined data types behave in the same way as the built-in data types • It is a type of polymorphism in which an operator is overloaded to give the user defined meaning of it 5
  • 6.
    DIFFERENCE BETWEEN OPERATOR FUNCTIONSAND NORMAL FUNCTIONS? • Operator functions are same as normal functions • The only differences are • name of an operator function is always operator keyword followed by symbol of operator • operator functions are called when the corresponding operator is used 6
  • 7.
    OPERATOR OVERLOADING CONTD… •Almost any operator can be overloaded in C++ • However there are few operator which can not be overloaded • Operator that are not overloaded are • Scope Resolution Operator (::) • sizeof • Member Selector (.) • Member Pointer Selector (*) • Ternary Operator (?:) 7
  • 8.
    OPERATOR OVERLOADING CONTD… Syntaxfor Operator Overloading Returntype Classname :: operator OperatorSymbol (argumentlist) { Function Body } 8
  • 9.
    IMPLEMENTING OPERATOR OVERLOADING •Operator overloading can be done by implementing a function which can be : • Member Function • Non-Member Function • Friend Function • Operator overloading function can be a member function if the Left operand is an Object of that class • If the Left operand is different, then Operator overloading function must be a non-member function • Operator overloading function can be made friend function if it needs access to the private and protected members of class 9
  • 10.
    RESTRICTIONS ON OPERATOROVERLOADING IN C++ • Following are some restrictions to be kept in mind while implementing operator overloading • Precedence and Associativity of an operator cannot be changed • Arity (numbers of Operands) cannot be changed. Unary operator remains unary, binary remains binary etc • No new operators can be created, only existing operators can be overloaded • Cannot redefine the meaning of a procedure (i.e., we cannot change how integers are added) 10
  • 11.
    OVERLOADING ARITHMETIC OPERATORSIN C++ • Arithmetic operator are most commonly used operator in C++ • Almost all arithmetic operator can be overloaded to perform arithmetic operation on user-defined data type 11
  • 12.
    OVERLOADING ARITHMETIC OPERATORSIN C++ #include <iostream> #include <conio.h> using namespace std; class Time { int h,m,s; public: Time() { h=0, m=0; s=0; } void setTime(); void show() { cout<<h<<":"<<m<<":"<<s; } //overloading '+' operator Time operator +(Time); }; void time::setTime() { cout << "n Enter the hour(0-11) "; cin >> h; cout << "n Enter the minute(0-59) "; cin >> m; cout << "n Enter the second(0-59) "; cin >> s; } Time Time::operator+(Time t1) //operator function { Time t; int a,b; a = s+t1.s; t.s = a%60; b = (a/60)+m+t1.m; t.m = b%60; t.h = (b/60)+h+t1.h; t.h = t.h%12; return t; } void main() { Time t1,t2,t3; cout << "n Enter the first time "; t1.setTime(); cout << "n Enter the second time "; t2.setTime(); t3 = t1 + t2; //adding of two time object using '+' operator //t3=t1.add(t2); - this is how the compiler treats the above cout << "n First time "; t1.show(); cout << "n Second time "; t2.show(); cout << "n Sum of times "; t3.show(); getch(); } 12
  • 13.
    OVERLOADING RELATIONAL OPERATORSIN C++ • You can also overload relational operators like ==, !=, >=, <= etc., to compare two object of any class 13
  • 14.
    OVERLOADING RELATIONAL OPERATORSIN C++ class Time { int hr, min, sec; public: // default constructor Time() { hr=0, min=0; sec=0; } // overloaded constructor Time(int h, int m, int s) { hr=h, min=m; sec=s; } //overloading '==' operator friend bool operator==(Time &t1, Time &t2); }; bool operator== (Time &t1, Time &t2) { return ( t1.hr == t2.hr && t1.min == t2.min && t1.sec == t2.sec ); } void main() { Time t1(3,15,45); Time t2(4,15,45); if(t1 == t2) { cout << "Both the time values are equal"; } else { cout << "Both the time values are not equal"; } } 14
  • 15.
    FRIEND FUNCTIONS • Afriend function of a class is defined outside that class scope • Friend function has the right to access all private and protected members of the class • Even though the prototypes for friend functions appear in the class definition, friends are not member functions 15
  • 16.
    WHY FRIEND FUNCTION •Special case when private members of the class need to be accessed directly without using object of that class • Used in Operator Overloading 16
  • 17.
    FRIEND FUNCTION EXAMPLE #include<iostream> usingnamespace std; class Demo{ private: int len; public: Demo() { len=0; } Demo(int l) { len=l; } friend void increase(Demo &d); void print(); }; void Demo::print(){ cout<<"Length is "<<len<<endl; } void increase(Demo &d) { d.len=d.len+10; } int main(){ Demo d(5); d.print(); increase(d); d.print();} 17
  • 18.
    OVERLOADING UNARY OPERATORS •Unary operators operate on only one operand • The increment operator ++ and decrement operator -- are examples of unary operators 18
  • 19.
    OVERLOADING UNARY OPERATOR //Overload ++ when used as prefix #include <iostream> using namespace std; class Count { private: int value; public: // Constructor to initialize count to 5 Count() : value(5) {} // Overload ++ when used as prefix void operator ++ () { ++value; } void display() { cout << "Count: " << value << endl; } }; int main() { Count count1; // Call the "void operator ++ ()" function ++count1; count1.display(); return 0; } 19
  • 20.
    OVERLOADING UNARY OPERATORS •For Postfix Operation: void operator ++ (int) { value++; } 20
  • 21.
    OVERLOADING UNARY OPERATORWITH RETURN VALUE #include <iostream> using namespace std; class Count { private: int value; public : // Constructor to initialize count to 5 Count() : value(5) {} // Overload ++ when used as prefix Count operator ++ () { Count temp; // Here, value is the value attribute of the calling object temp.value = ++value; return temp; } / //Overload ++ when used as postfix Count operator ++ (int) { Count temp; // Here, value is the value attribute of the calling object temp.value = value++; return temp; } void display() { cout << "Count: " << value << endl; } }; int main() { Count count1, result; // Call the "Count operator ++ ()" function result = ++count1; result.display(); // Call the "Count operator ++ (int)" function result = count1++; result.display(); return 0; } 21
  • 22.
    OVERLOADING ASSIGNMENT OPERATOR •The assignment operator (operator=) is used to copy values from one object to another already existing object 22
  • 23.
    OVERLOADING ASSIGNMENT OPERATOR #include<iostream> using namespace std; class Distance { private: int feet; // 0 to infinite int inches; // 0 to 12 public: // required constructors Distance() { feet = 0; inches = 0; } Distance(int f, int i) { feet = f; inches = i; } void operator = (const Distance &D ) { feet = D.feet; inches = D.inches; } // method to display distance void displayDistance() { cout << "F: " << feet << " I:" << inches << endl; } }; int main() { Distance D1(11, 10), D2(5, 11); cout << "First Distance : "; D1.displayDistance(); cout << "Second Distance :"; D2.displayDistance(); // use assignment operator D1 = D2; cout << "First Distance :"; D1.displayDistance(); return 0; } 23
  • 24.
    RULES FOR OPERATOROVERLOADING • Only built-in operators can be overloaded. If some operators are not present in C++, we cannot overload them. • The arity of the operators cannot be changed • The precedence of the operators remains same • We cannot overload operators for built-in data types. At least one user defined data types must be there. • The assignment “=”, subscript “[]”, function call “()” and arrow operator “->” these operators must be defined as member functions, not the friend functions. • Some operators like assignment “=”, address “&” and comma “,” are by default overloaded. 24
  • 25.
  • 26.
    INHERITANCE • Introduction: • Thecapability of a class to derive properties and characteristics from another class is called Inheritance • Inheritance is one of the most important feature of Object Oriented Programming • Sub Class: The class that inherits properties from another class is called Sub class or Derived Class • Super Class: The class whose properties are inherited by sub class is called Base Class or Super class 26
  • 27.
    WHY INHERITANCE? • Reusability •Consider a group of vehicles Bus, Car and Truck. • We need to create classes for Bus, Car and Truck • Assume the methods fuelAmount(), capacity(), applyBrakes() will be same for all of the three classes • If we create these classes avoiding inheritance then we have to write all of these functions in each of the three classes 27
  • 28.
    WHY INHERITANCE CONTD… •You can clearly see that above process results in duplication of same code 3 times • Disadvantages: • Increase in error rate and data redundancy • To avoid this type of situation, inheritance is used • If we create a class Vehicle and write these three functions in it and inherit the rest of the classes from the vehicle class, then we can simply avoid the duplication of data and increase re-usability 28
  • 29.
    IMPLEMENTING INHERITANCE INC++ • For creating a sub-class which is inherited from the base class we have to follow the below syntax: class subclass_name : access_specifier base_class_name { //subclass body }; • subclass_name is the name of the sub class • access_mode is the mode in which you want to inherit this sub class • base_class_name is the name of the base class from which you want to inherit the sub class 29
  • 30.
    INHERITANCE EXAMPLE #include <bits/stdc++.h> usingnamespace std; //Base class class Parent { public: int id_p; }; // Sub class inheriting from Base Class(Parent) class Child : public Parent { public: int id_c; }; //main function int main() { Child obj1; // An object of class child has all data members // and member functions of class parent obj1.id_c = 7; obj1.id_p = 91; cout << "Child id is " << obj1.id_c << endl; cout << "Parent id is " << obj1.id_p << endl; return 0; } 30
  • 31.
  • 32.
    MODES OF INHERITANCE •Public mode: • If we derive a sub class from a public base class • Then the public member of the base class will become public in the derived class and protected members of the base class will become protected in derived class • Protected mode: • If we derive a sub class from a Protected base class • Then both public member and protected members of the base class will become protected in derived class • Private mode: • If we derive a sub class from a Private base class • Then both public member and protected members of the base class will become Private in derived class • Note: Private members of a base class cannot be directly accessed in derived class, while protected members can be directly accessed 32
  • 33.
    MODES OF INHERITANCECONTD… class A { public: int x; protected: int y; private: int z; }; class B : public A { // x is public // y is protected // z is not accessible from B }; class C : protected A { // x is protected // y is protected // z is not accessible from C }; class D : private A // 'private' is default for classes { // x is private // y is private // z is not accessible from D }; 33
  • 34.
  • 35.
  • 36.
    TYPES OF INHERITANCE •Single Inheritance • Multiple Inheritance • Multilevel Inheritance • Hierarchical Inheritance • Hybrid Inheritance • Multipath Inheritance 36
  • 37.
  • 38.
    SINGLE INHERITANCE • SingleInheritance: • In single inheritance, a class is allowed to inherit from only one class • One sub class is inherited by one base class only 38
  • 39.
    SINGLE INHERITANCE SYNTAX classsubclass_name : access_mode base_class1 { //body of subclass }; 39
  • 40.
  • 41.
    SINGLE INHERITANCE EXAMPLE #include<iostream> using namespace std; // base class class Vehicle { public: Vehicle() { cout << "This is a Vehicle" << endl; } }; // sub class derived from a single base classes class Car: public Vehicle{ }; // main function int main() { // creating object of sub class will // invoke the constructor of base classes Car obj; return 0; } 41
  • 42.
  • 43.
    MULTIPLE INHERITANCE • MultipleInheritance: • Multiple Inheritance is a feature of C++ where a class can inherit from more than one classes • i.e one sub class is inherited from more than one base classes 43
  • 44.
  • 45.
    MULTIPLE INHERITANCE SYNTAX classsubclass_name : access_mode base_class1, access_mode base_class2, .... { //body of subclass }; 45
  • 46.
    MULTIPLE INHERITANCE EXAMPLE #include<iostream> using namespace std; // first base class class Vehicle { public: Vehicle() { cout << "This is a Vehicle" << endl; } }; // second base class class FourWheeler { public: FourWheeler() { cout << "This is a 4 wheeler Vehicle" << endl; } }; // sub class derived from two base classes class Car: public Vehicle, public FourWheeler { }; // main function int main() { // creating object of sub class will // invoke the constructor of base classes Car obj; return 0; } 46
  • 47.
  • 48.
    MULTILEVEL INHERITANCE • MultilevelInheritance: • In this type of inheritance, a derived class is created from another derived class 48
  • 49.
  • 50.
    MULTILEVEL INHERITANCE EXAMPLE #include<iostream> using namespace std; // base class class Vehicle { public: Vehicle() { cout << "This is a Vehicle" << endl; } }; // first sub_class derived from class vehicle class fourWheeler: public Vehicle { public: fourWheeler() { cout<<"Objects with 4 wheels are vehicles"<<endl; } }; // sub class derived from the derived base class fourWheeler class Car: public fourWheeler{ public: Car() { cout<<"Car has 4 Wheels"<<endl; } }; // main function int main() { //creating object of sub class will //invoke the constructor of base classes Car obj; return 0; } 50
  • 51.
  • 52.
    HIERARCHICAL INHERITANCE • HierarchicalInheritance: • In this type of inheritance, more than one sub class is inherited from a single base class • i.e. more than one derived class is created from a single base class. 52
  • 53.
  • 54.
    HIERARCHICAL INHERITANCE EXAMPLE #include<iostream> using namespace std; // base class class Vehicle { public: Vehicle() { cout << "This is a Vehicle" << endl; } }; // first sub class class Car: public Vehicle { }; // second sub class class Bus: public Vehicle { }; // main function int main() { // creating object of sub class will // invoke the constructor of base class Car obj1; Bus obj2; return 0; } 54
  • 55.
  • 56.
    HYBRID INHERITANCE • Hybrid(Virtual) Inheritance: • Hybrid Inheritance is implemented by combining more than one type of inheritance • For example: Combining Hierarchical inheritance and Multiple Inheritance 56
  • 57.
  • 58.
    HYBRID INHERITANCE EXAMPLE //C++ program for Hybrid Inheritance #include <iostream> using namespace std; // base class class Vehicle { public: Vehicle() { cout << "This is a Vehicle" << endl; } }; //base class class Fare { public: Fare() { cout<<"Fare of Vehiclen"; } }; // first sub class class Car: public Vehicle { }; // second sub class class Bus: public Vehicle, public Fare { }; // main function int main() { // creating object of sub class will // invoke the constructor of base class Bus obj2; return 0; } 58
  • 59.
  • 60.
    MULTIPATH INHERITANCE • MultipathInheritance: • A special case of hybrid inheritance • A derived class with two base classes and these two base classes have one common base class is called multipath inheritance • An ambiguity can arise in this type of inheritance • Example: • Combining Hierarchical inheritance and Multiple Inheritance 60
  • 61.
    MULTIPATH INHERITANCE EXAMPLE //C++ program demonstrating ambiguity in Multipath Inheritance #include <conio.h> #include <iostream.h> class ClassA { public: int a; }; class ClassB : public ClassA { public: int b; }; class ClassC : public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; void main() { ClassD obj; // obj.a = 10; //Statement 1, Error // obj.a = 100; //Statement 2, Error obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout << "n A from ClassB : " << obj.ClassB::a; cout << "n A from ClassC : " << obj.ClassC::a; cout << "n B : " << obj.b; cout << "n C : " << obj.c; cout << "n D : " << obj.d; } 61
  • 62.
  • 63.
    AMBIGUITY IN MULTIPATHINHERITANCE • In the above example, both ClassB & ClassC inherit ClassA, they both have single copy of ClassA • However ClassD inherit both ClassB & ClassC, therefore ClassD have two copies of ClassA, one from ClassB and another from ClassC • If we need to access the data member a of ClassA through the object of ClassD, we must specify the path from which a will be accessed, whether it is from ClassB or ClassC, bco’z compiler can’t differentiate between two copies of ClassA in ClassD 63
  • 64.
    HOW TO AVOIDAMBIGUITY IN MULTIPATH INHERITANCE? • There are 2 ways to avoid this ambiguity: • Avoiding ambiguity using scope resolution operator: • Using scope resolution operator we can manually specify the path from which data member a will be accessed, as shown in statement 3 and 4, in the above example. • Example: • obj.ClassB::a = 10; //Statement 3 • obj.ClassC::a = 100; //Statement 4 • Avoiding ambiguity using virtual base class: • Explanation using a programming Example 64
  • 65.
    SOLUTION 1 FORRESOLVING AMBIGUITY – USING SCOPE RESOLUTION OPERATOR // C++ program demonstrating ambiguity in Multipath Inheritance #include <conio.h> #include <iostream.h> class ClassA { public: int a; }; class ClassB : public ClassA { public: int b; }; class ClassC : public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; void main() { ClassD obj; obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout << "n A from ClassB : " << obj.ClassB::a; cout << "n A from ClassC : " << obj.ClassC::a; cout << "n B : " << obj.b; cout << "n C : " << obj.c; cout << "n D : " << obj.d; } 65
  • 66.
    SOLUTION 2 FORRESOLVING AMBIGUITY – USING VIRTUAL BASE CLASSES #include<iostream.h> #include<conio.h> class ClassA { public: int a; }; class ClassB : virtual public ClassA { public: int b; }; class ClassC : virtual public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; void main() { ClassD obj; obj.a = 10; //Statement 3 obj.a = 100; //Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout<< "n A : "<< obj.a; cout<< "n B : "<< obj.b; cout<< "n C : "<< obj.c; cout<< "n D : "<< obj.d; } Note: According to the above example, ClassD has only one copy of ClassA, therefore, statement 4 will overwrite the value of a, given at statement 3. 66
  • 67.
  • 68.
    VIRTUAL BASE CLASSES •Virtual base classes are used in virtual inheritance • It is to prevent multiple “instances” of a given class appearing in an inheritance hierarchy when using multiple inheritances 68
  • 69.
    NEED FOR VIRTUALBASE CLASSES • Consider the situation where we have one class A • This class is A is inherited by two other classes B and C • Both these class are inherited into another in a new class D as shown in figure • The data members/function of class A are inherited twice to class D - One through class B and second through class C • When any data / function member of class A is accessed by an object of class D, ambiguity arises as to which data/function member would be called? (One inherited through B or the other inherited through C) • This confuses compiler and it displays error 69
  • 70.
    AMBIGUITY RAISED DUETO INHERITANCE #include <iostream> using namespace std; class A { public: void show() { cout << "Hello form A n"; } }; class B : public A { }; class C : public A { }; class D : public B, public C { }; int main() { D object; object.show(); } Output: Error 70
  • 71.
    HOW TO RESOLVETHE AMBIGUITY? • Virtual base classes offer a way to save space and avoid ambiguities in class hierarchies that use multiple inheritances • When a base class is specified as a virtual base, it can act as an indirect base more than once without duplication of its data members • A single copy of its data members is shared by all the base classes that use virtual base • To resolve this ambiguity when class A is inherited in both class B and class C, it is declared as virtual base class by placing a keyword virtual • Syntax 1: class B : virtual public A { }; • Syntax 2: class C : virtual public A { }; • Now only one copy of data/function member will be copied to class C and class B and class A becomes the virtual base class • Note: virtual can be placed before or after public keyword 71
  • 72.
    SOLUTION FOR AMBIGUITY– VIRTUAL BASE CLASSES ##include <iostream> using namespace std; class A { public: int a; A() // constructor { a = 10; } }; class B : public virtual A { }; class C : public virtual A { }; class D : public B, public C { }; int main() { D object; // object creation of class d cout << "a = " << object.a << endl; return 0; } 72
  • 73.
  • 74.
    ABSTRACT CLASSES • AbstractClass is a class which contains atleast one Pure Virtual function in it • Abstract classes are used to provide an Interface for its sub classes • Classes inheriting an Abstract Class must provide definition to the pure virtual function, otherwise they will also become abstract class 74
  • 75.
    CHARACTERISTICS OF ABSTRACTCLASS • Abstract class cannot be instantiated, but pointers and references of Abstract class type can be created • Abstract class can have normal functions and variables along with a pure virtual function • Abstract classes are mainly used for Upcasting, so that its derived classes can use its interface • Classes inheriting an Abstract Class must implement all pure virtual functions, or else they will become Abstract too 75
  • 76.
  • 77.
    UPCASTING IN C++ •Upcasting is using the Super class's reference or pointer to refer to a Sub class's object or • The act of converting a Sub class's reference or pointer into its Super class's reference or pointer is called Upcasting 77
  • 78.
    UPCASTING EXAMPLE class Super { intx; public: void funBase() { cout << "Super function"; } }; class Sub:public Super { int y; }; int main() { Super* ptr; // Super class pointer Sub obj; ptr = &obj; Super &ref; // Super class's reference ref=obj; } 78
  • 79.
  • 80.
    VIRTUAL FUNCTIONS INC++ • A virtual function is a member function in the base class that are expected to redefine in derived classes • Functions are declared with a virtual keyword in base class • Basically, a virtual function is used in the base class in order to ensure that the function is overridden • This especially applies to cases where a pointer of base class points to an object of a derived class • They are mainly used to achieve Runtime polymorphism • The resolving of function call is done at Run-time 80
  • 81.
    VIRTUAL FUNCTIONS CONTD… •Rules for Virtual Functions • Virtual functions cannot be static • A virtual function can be a friend function of another class • Virtual functions should be accessed using pointer or reference of base class type to achieve run time polymorphism • The prototype of virtual functions should be the same in the base as well as derived class • They are always defined in the base class and overridden in a derived class. It is not mandatory for the derived class to override (or re-define the virtual function), in that case, the base class version of the function is used • A class may have virtual destructor but it cannot have a virtual constructor 81
  • 82.
  • 83.
    PURE VIRTUAL FUNCTIONSIN C++ • Pure virtual Functions are virtual functions with no definition • They start with virtual keyword and ends with = 0 • Syntax: • virtual void f() = 0; 83
  • 84.
    PURE VIRTUAL FUNCTIONSEXAMPLE class Base { public: virtual void show() = 0; // Pure Virtual Function }; class Derived:public Base { public: void show() { cout << "Implementation of Virtual Function in Derived classn"; } }; int main() { Base obj; //Compile Time Error Base *b; Derived d; b = &d; b->show(); } Note: In the above example Base class is abstract, with pure virtual show() function, hence we cannot create object of base class. 84
  • 85.
    WHY CAN'T WECREATE OBJECT OF AN ABSTRACT CLASS? • When we create a pure virtual function in Abstract class, we reserve a slot for a function in the VTABLE but doesn't put any address in that slot • Hence the VTABLE will be incomplete • As the VTABLE for Abstract class is incomplete, hence the compiler will not let the creation of object for such class and will display an errror message whenever you try to do so 85
  • 86.
  • 87.
    PURE VIRTUAL DEFINITIONS •Pure Virtual functions can be given a small definition in the Abstract class, which you want all the derived classes to have • Still you cannot create object of Abstract class • Also, the Pure Virtual function must be defined outside the class definition • If you will define it inside the class definition, complier will give an error • Inline pure virtual definition is Illegal 87
  • 88.
    PURE VIRTUAL DEFINITIONEXAMPLE // Abstract base class class Base { public: virtual void show() = 0; //Pure Virtual Function }; void Base :: show() //Pure Virtual definition { cout << "Pure Virtual definitionn"; } class Derived:public Base { public: void show() { cout << "Implementation of Virtual Function in Derived classn"; } }; int main() { Base *b; Derived d; b = &d; b->show(); } 88
  • 89.
  • 90.
    ADVANTAGES OF INHERITANCE •Inheritance promotes reusability: • When a class inherits or derives another class, it can access all the functionality of inherited class • Reusability enhanced reliability: • The base class code will be already tested and debugged • As the existing code is reused, it leads to less development and maintenance costs • Inheritance makes the sub classes follow a standard interface • Inheritance helps to reduce code redundancy and supports code extensibility • Inheritance facilitates creation of class libraries 90
  • 91.
    DISADVANTAGES OF INHERITANCE •Inherited functions work slower than normal function as there is indirection • Improper use of inheritance may lead to wrong solutions • Often, data members in the base class are left unused which may lead to memory wastage • Inheritance increases the coupling between base class and derived class. A change in base class will affect all the child classes. 91
  • 92.
    FUNCTIONS THAT ARENEVER INHERITED • Constructors and Destructors are never inherited and hence never overrided • Assignment Operator (=) is never inherited (It can be overloaded but can never be inherited) 92
  • 93.