You are on page 1of 45

Unit – 5

Inheritance
C++ Inheritance
In C++, inheritance is a process in which one object acquires all the properties and
behaviors of its parent object automatically. In such way, you can reuse, extend or modify
the attributes and behaviors which are defined in other class.

In C++, the class which inherits the members of another class is called derived class and
the class whose members are inherited is called base class. The derived class is the
specialized class for the base class.

One of the most important concepts in object-oriented programming is that of


inheritance. Inheritance allows us to define a class in terms of another class, which
makes it easier to create and maintain an application. This also provides an opportunity
to reuse the code functionality and fast implementation time.
When creating a class, instead of writing completely new data members and member
functions, the programmer can designate that the new class should inherit the
members of an existing class. This existing class is called the base class, and the new
class is referred to as the derived class.
The idea of inheritance implements the is a relationship. For example, mammal IS-A
animal, dog IS-A mammal hence dog IS-A animal as well and so on.

Base and Derived Classes


A class can be derived from more than one classes, which means it can inherit data
and functions from multiple base classes. To define a derived class, we use a class
derivation list to specify the base class(es). A class derivation list names one or more
base classes and has the form −
class derived-class: access-specifier base-class
Where access-specifier is one of public, protected, or private, and base-class is the
name of a previously defined class. If the access-specifier is not used, then it is private
by default.
Consider a base class Shape and its derived class Rectangle as follows −
Live Demo
#include <iostream>

using namespace std;

// Base class
class Shape {
public:
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}

protected:
int width;
int height;
};

// Derived class
class Rectangle: public Shape {
public:
int getArea() {
return (width * height);
}
};

int main(void) {
Rectangle Rect;

Rect.setWidth(5);
Rect.setHeight(7);

// Print the area of the object.


cout << "Total area: " << Rect.getArea() << endl;

return 0;
}
When the above code is compiled and executed, it produces the following result −
Total area: 35

Access Control and Inheritance


A derived class can access all the non-private members of its base class. Thus base-
class members that should not be accessible to the member functions of derived
classes should be declared private in the base class.
We can summarize the different access types according to - who can access them in
the following way −

Access public protected private


Same class yes yes yes

Derived classes yes yes no

Outside classes yes no no

A derived class inherits all base class methods with the following exceptions −

 Constructors, destructors and copy constructors of the base class.


 Overloaded operators of the base class.
 The friend functions of the base class.
When deriving a class from a base class, the base class may be inherited
through public, protected or private inheritance. The type of inheritance is specified
by the access-specifier as explained above.
We hardly use protected or private inheritance, but public inheritance is commonly
used. While using different type of inheritance, following rules are applied −
 Public Inheritance − When deriving a class from a public base class, public members of
the base class become public members of the derived class and protected members of
the base class become protected members of the derived class. A base
class's private members are never accessible directly from a derived class, but can be
accessed through calls to the public and protected members of the base class.
 Protected Inheritance − When deriving from a protected base
class, public and protected members of the base class become protected members of the
derived class.
 Private Inheritance − When deriving from a private base
class, public and protected members of the base class become private members of the
derived class.

Advantage of C++ Inheritance


Code reusability: Now you can reuse the members of your parent class. So, there is no
need to define the member again. So less code is required in the class.

Types of Inheritance
C++ supports five types of inheritance:
o Single inheritance
o Multiple inheritance
o Hierarchical inheritance
o Multilevel inheritance
o Hybrid inheritance

Derived Classes
A Derived class is defined as the class derived from the base class.

The Syntax of Derived class:

1. class derived_class_name :: visibility-mode base_class_name


2. {
3. // body of the derived class.
4. }

Where,

derived_class_name: It is the name of the derived class.


visibility mode: The visibility mode specifies whether the features of the base class are
publicly inherited or privately inherited. It can be public or private.

base_class_name: It is the name of the base class.

o When the base class is privately inherited by the derived class, public members of
the base class becomes the private members of the derived class. Therefore, the
public members of the base class are not accessible by the objects of the derived
class only by the member functions of the derived class.
o When the base class is publicly inherited by the derived class, public members of the
base class also become the public members of the derived class. Therefore, the
public members of the base class are accessible by the objects of the derived class
as well as by the member functions of the base class.

Note:

o In C++, the default mode of visibility is private.


o The private members of the base class are never inherited.

C++ Single Inheritance


Single inheritance is defined as the inheritance in which a derived class is inherited from
the only one base class.

Where 'A' is the base class, and 'B' is the derived class.

C++ Single Level Inheritance Example: Inheriting Fields


When one class inherits another class, it is known as single level inheritance. Let's see the
example of single level inheritance which inherits the fields only.
1. #include <iostream>
2. using namespace std;
3. class Account {
4. public:
5. float salary = 60000;
6. };
7. class Programmer: public Account {
8. public:
9. float bonus = 5000;
10. };
11. int main(void) {
12. Programmer p1;
13. cout<<"Salary: "<<p1.salary<<endl;
14. cout<<"Bonus: "<<p1.bonus<<endl;
15. return 0;
16. }

Output:

Salary: 60000
Bonus: 5000

In the above example, Employee is the base class and Programmer is the derived class.

C++ Single Level Inheritance Example: Inheriting


Methods
Let's see another example of inheritance in C++ which inherits methods only.

1. #include <iostream>
2. using namespace std;
3. class Animal {
4. public:
5. void eat() {
6. cout<<"Eating..."<<endl;
7. }
8. };
9. class Dog: public Animal
10. {
11. public:
12. void bark(){
13. cout<<"Barking...";
14. }
15. };
16. int main(void) {
17. Dog d1;
18. d1.eat();
19. d1.bark();
20. return 0;
21. }

Output:

Eating...
Barking...

Let's see a simple example.

1. #include <iostream>
2. using namespace std;
3. class A
4. {
5. int a = 4;
6. int b = 5;
7. public:
8. int mul()
9. {
10. int c = a*b;
11. return c;
12. }
13. };
14.
15. class B : private A
16. {
17. public:
18. void display()
19. {
20. int result = mul();
21. std::cout <<"Multiplication of a and b is : "<<result<< std::endl;
22. }
23. };
24. int main()
25. {
26. B b;
27. b.display();
28.
29. return 0;
30. }

Output:

Multiplication of a and b is : 20

In the above example, class A is privately inherited. Therefore, the mul() function of class
'A' cannot be accessed by the object of class B. It can only be accessed by the member
function of class B.

How to make a Private Member Inheritable


The private member is not inheritable. If we modify the visibility mode by making it public,
but this takes away the advantage of data hiding.

C++ introduces a third visibility modifier, i.e., protected. The member which is declared as
protected will be accessible to all the member functions within the class as well as the class
immediately derived from it.

Visibility modes can be classified into three categories:

o Public: When the member is declared as public, it is accessible to all the functions of
the program.
o Private: When the member is declared as private, it is accessible within the class
only.
o Protected: When the member is declared as protected, it is accessible within its
own class as well as the class immediately derived from it.

Visibility of Inherited Members


Base class visibility Derived class visibility

Public Private Protect

Private Not Inherited Not Inherited Not In

Protected Protected Private Prote

Public Public Private Prote

C++ Multilevel Inheritance


Multilevel inheritance is a process of deriving a class from another derived class.

C++ Multi Level Inheritance Example


When one class inherits another class which is further inherited by another class, it is known
as multi level inheritance in C++. Inheritance is transitive so the last derived class acquires
all the members of all its base classes.

Let's see the example of multi level inheritance in C++.

1. #include <iostream>
2. using namespace std;
3. class Animal {
4. public:
5. void eat() {
6. cout<<"Eating..."<<endl;
7. }
8. };
9. class Dog: public Animal
10. {
11. public:
12. void bark(){
13. cout<<"Barking..."<<endl;
14. }
15. };
16. class BabyDog: public Dog
17. {
18. public:
19. void weep() {
20. cout<<"Weeping...";
21. }
22. };
23. int main(void) {
24. BabyDog d1;
25. d1.eat();
26. d1.bark();
27. d1.weep();
28. return 0;
29. }

Output:

Eating...
Barking...
Weeping...

C++ Multiple Inheritance


Multiple inheritance is the process of deriving a new class that inherits the attributes from
two or more classes.
Syntax of the Derived class:

1. class D : visibility B-1, visibility B-2, ?


2. {
3. // Body of the class;
4. }

Let's see a simple example of multiple inheritance.

1. #include <iostream>
2. using namespace std;
3. class A
4. {
5. protected:
6. int a;
7. public:
8. void get_a(int n)
9. {
10. a = n;
11. }
12. };
13.
14. class B
15. {
16. protected:
17. int b;
18. public:
19. void get_b(int n)
20. {
21. b = n;
22. }
23. };
24. class C : public A,public B
25. {
26. public:
27. void display()
28. {
29. std::cout << "The value of a is : " <<a<< std::endl;
30. std::cout << "The value of b is : " <<b<< std::endl;
31. cout<<"Addition of a and b is : "<<a+b;
32. }
33. };
34. int main()
35. {
36. C c;
37. c.get_a(10);
38. c.get_b(20);
39. c.display();
40.
41. return 0;
42. }

Output:

The value of a is : 10
The value of b is : 20
Addition of a and b is : 30

In the above example, class 'C' inherits two base classes 'A' and 'B' in a public mode.

Ambiquity Resolution in Inheritance


Ambiguity can be occurred in using the multiple inheritance when a function with the same
name occurs in more than one base class.

Let's understand this through an example:

1. #include <iostream>
2. using namespace std;
3. class A
4. {
5. public:
6. void display()
7. {
8. std::cout << "Class A" << std::endl;
9. }
10. };
11. class B
12. {
13. public:
14. void display()
15. {
16. std::cout << "Class B" << std::endl;
17. }
18. };
19. class C : public A, public B
20. {
21. void view()
22. {
23. display();
24. }
25. };
26. int main()
27. {
28. C c;
29. c.display();
30. return 0;
31. }

Output:

error: reference to 'display' is ambiguous


display();
o The above issue can be resolved by using the class resolution operator with the
function. In the above example, the derived class code can be rewritten as:

1. class C : public A, public B


2. {
3. void view()
4. {
5. A :: display(); // Calling the display() function of class A.
6. B :: display(); // Calling the display() function of class B.
7.
8. }
9. };

An ambiguity can also occur in single inheritance.


Consider the following situation:

1. class A
2. {
3. public:
4. void display()
5. {
6. cout<<?Class A?;
7. }
8. } ;
9. class B
10. {
11. public:
12. void display()
13. {
14. cout<<?Class B?;
15. }
16. } ;

In the above case, the function of the derived class overrides the method of the base class.
Therefore, call to the display() function will simply call the function defined in the derived
class. If we want to invoke the base class function, we can use the class resolution operator.

1. int main()
2. {
3. B b;
4. b.display(); // Calling the display() function of B class.
5. b.B :: display(); // Calling the display() function defined in B class.
6. }

C++ Hybrid Inheritance


Hybrid inheritance is a combination of more than one type of inheritance.
Let's see a simple example:

1. #include <iostream>
2. using namespace std;
3. class A
4. {
5. protected:
6. int a;
7. public:
8. void get_a()
9. {
10. std::cout << "Enter the value of 'a' : " << std::endl;
11. cin>>a;
12. }
13. };
14.
15. class B : public A
16. {
17. protected:
18. int b;
19. public:
20. void get_b()
21. {
22. std::cout << "Enter the value of 'b' : " << std::endl;
23. cin>>b;
24. }
25. };
26. class C
27. {
28. protected:
29. int c;
30. public:
31. void get_c()
32. {
33. std::cout << "Enter the value of c is : " << std::endl;
34. cin>>c;
35. }
36. };
37.
38. class D : public B, public C
39. {
40. protected:
41. int d;
42. public:
43. void mul()
44. {
45. get_a();
46. get_b();
47. get_c();
48. std::cout << "Multiplication of a,b,c is : " <<a*b*c<< std::endl;
49. }
50. };
51. int main()
52. {
53. D d;
54. d.mul();
55. return 0;
56. }

Output:

Enter the value of 'a' :


10
Enter the value of 'b' :
20
Enter the value of c is :
30
Multiplication of a,b,c is : 6000
C++ Hierarchical Inheritance
Hierarchical inheritance is defined as the process of deriving more than one class from a
base class.

Syntax of Hierarchical inheritance:

1. class A
2. {
3. // body of the class A.
4. }
5. class B : public A
6. {
7. // body of class B.
8. }
9. class C : public A
10. {
11. // body of class C.
12. }
13. class D : public A
14. {
15. // body of class D.
16. }

Let's see a simple example:

1. #include <iostream>
2. using namespace std;
3. class Shape // Declaration of base class.
4. {
5. public:
6. int a;
7. int b;
8. void get_data(int n,int m)
9. {
10. a= n;
11. b = m;
12. }
13. };
14. class Rectangle : public Shape // inheriting Shape class
15. {
16. public:
17. int rect_area()
18. {
19. int result = a*b;
20. return result;
21. }
22. };
23. class Triangle : public Shape // inheriting Shape class
24. {
25. public:
26. int triangle_area()
27. {
28. float result = 0.5*a*b;
29. return result;
30. }
31. };
32. int main()
33. {
34. Rectangle r;
35. Triangle t;
36. int length,breadth,base,height;
37. std::cout << "Enter the length and breadth of a rectangle: " << std::endl;
38. cin>>length>>breadth;
39. r.get_data(length,breadth);
40. int m = r.rect_area();
41. std::cout << "Area of the rectangle is : " <<m<< std::endl;
42. std::cout << "Enter the base and height of the triangle: " << std::endl;
43. cin>>base>>height;
44. t.get_data(base,height);
45. float n = t.triangle_area();
46. std::cout <<"Area of the triangle is : " << n<<std::endl;
47. return 0;
48. }

Output:

Enter the length and breadth of a rectangle:


23
20
Area of the rectangle is : 460
Enter the base and height of the triangle:
2
5
Area of the triangle is : 5

Virtual base class and Abstract Class


Virtual base classes, used in virtual inheritance, is a way of preventing multiple "instances" of
a given class appearing in an inheritance hierarchy when using multiple inheritance. Answer:
An abstract class is one, which is never instantiated. The objects of an abstract base
class are never created.

Characteristics of Abstract Class


1. Abstract class cannot be instantiated, but pointers and refrences of Abstract class type can
be created.
2. Abstract class can have normal functions and variables along with a pure virtual function.
3. Abstract classes are mainly used for Upcasting, so that its derived classes can use its
interface.
4. Classes inheriting an Abstract Class must implement all pure virtual functions, or else
they will become Abstract too.

5. Example of Abstract Class in C++


6. Below we have a simple example where we have defined an abstract class,
7. //Abstract base class
8. class Base
9. {
10. public:
11. virtual void show() = 0; // Pure Virtual Function
12. };
13.
14. class Derived:public Base
15. {
16. public:
17. void show()
18. {
19. cout << "Implementation of Virtual Function in Derived class\n";
20. }
21. };
22.
23. int main()
24. {
25. Base obj; //Compile Time Error
26. Base *b;
27. Derived d;
28. b = &d;
29. b->show();
30. }
31.
32. Implementation of Virtual Function in Derived class
33. In the above example Base class is abstract, with pure virtual show() function, hence we
cannot create object of base class.
34.
35. Why can't we create Object of an Abstract Class?
36. When we create a pure virtual function in Abstract class, we reserve a slot for a function
in the VTABLE(studied in last topic), but doesn't put any address in that slot. Hence the
VTABLE will be incomplete.
37. 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.

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.

// Abstract base class


class Base
{
public:
virtual void show() = 0; //Pure Virtual Function
};

void Base :: show() //Pure Virtual definition


{
cout << "Pure Virtual definition\n";
}

class Derived:public Base


{
public:
void show()
{
cout << "Implementation of Virtual Function in Derived class\n";
}
};

int main()
{
Base *b;
Derived d;
b = &d;
b->show();
}

Implementation of Virtual Function in Derived class

Pure Virtual Functions in C++


Pure virtual Functions are virtual functions with no definition. They start
with virtual keyword and ends with = 0. Here is the syntax for a pure virtual function,
virtual void f() = 0;

Polymorphism in C++
The word polymorphism means having many forms. In simple words, we can define
polymorphism as the ability of a message to be displayed in more than one form.
Real life example of polymorphism, a person at the same time can have different characteristic.
Like a man at the same time is a father, a husband, an employee. So the same person posses
different behavior in different situations. This is called polymorphism.
Polymorphism is considered as one of the important features of Object Oriented Programming.
In C++ polymorphism is mainly divided into two types:
 Compile time Polymorphism
 Runtime Polymorphism

1. Compile time polymorphism: This type of polymorphism is achieved by function


overloading or operator overloading.

 Function Overloading: When there are multiple functions with same name but
different parameters then these functions are said to be overloaded. Functions can be
overloaded by change in number of arguments or/and change in type of
arguments.
Rules of Function Overloading
// C++ program for function overloading
#include <bits/stdc++.h>

using namespace std;


class Geeks
{
public:

// function with 1 int parameter


void func(int x)
{
cout << "value of x is " << x << endl;
}

// function with same name but 1 double parameter


void func(double x)
{
cout << "value of x is " << x << endl;
}

// function with same name and 2 int parameters


void func(int x, int y)
{
cout << "value of x and y is " << x << ", " << y << endl;
}
};

int main() {

Geeks obj1;

// Which function is called will depend on the parameters passed


// The first 'func' is called
obj1.func(7);

// The second 'func' is called


obj1.func(9.132);

// The third 'func' is called


obj1.func(85,64);
return 0;
}
Output:
value of x is 7
value of x is 9.132
value of x and y is 85, 64
In the above example, a single function named func acts differently in three different
situations which is the property of polymorphism.
 Operator Overloading: C++ also provide option to overload operators. For example,
we can make the operator (‘+’) for string class to concatenate two strings. We know
that this is the addition operator whose task is to add two operands. So a single
operator ‘+’ when placed between integer operands , adds them and when placed
between string operands, concatenates them.
Example:
// CPP program to illustrate
// Operator Overloading
#include<iostream>
using namespace std;

class Complex {
private:
int real, imag;
public:
Complex(int r = 0, int i =0) {real = r; imag = i;}

// This is automatically called when '+' is used with


// between two Complex objects
Complex operator + (Complex const &obj) {
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
void print() { cout << real << " + i" << imag << endl; }
};

int main()
{
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2; // An example call to "operator+"
c3.print();
}
Output:
12 + i9
In the above example the operator ‘+’ is overloaded. The operator ‘+’ is an addition
operator and can add two numbers(integers or floating point) but here the operator is
made to perform addition of two imaginary or complex numbers. To learn operator
overloading in details visit this link.
2. Runtime polymorphism: This type of polymorphism is achieved by Function Overriding.
 Function overriding on the other hand occurs when a derived class has a definition
for one of the member functions of the base class. That base function is said to
be overridden.
// C++ program for function overriding

#include <bits/stdc++.h>
using namespace std;

class base
{
public:
virtual void print ()
{ cout<< "print base class" <<endl; }

void show ()
{ cout<< "show base class" <<endl; }
};

class derived:public base


{
public:
void print () //print () is already virtual function in derived class, we could also declared as virtual v
{ cout<< "print derived class" <<endl; }

void show ()
{ cout<< "show derived class" <<endl; }
};

//main function
int main()
{
base *bptr;
derived d;
bptr = &d;

//virtual function, binded at runtime (Runtime polymorphism)


bptr->print();

// Non-virtual function, binded at compile time


bptr->show();

return 0;
}
Output:
print derived class
show base class
C++ Polymorphism. Polymorphism means more than one function with same
name, with different working. ... Virtual function is an example of dynamic
polymorphism. Static polymorphism is also known as early binding and compile-
time polymorphism. Dynamic polymorphism is also known as late binding and
run-time polymorphism.
Polymorphism means more than one function with same name, with different working.
Polymorphism can be static or dynamic. In static polymorphism memory will be
allocated at compile-time. In dynamic polymorphism memory will be allocated at run-
time. Both function overloading and operator overloading are an examples of static
polymorphism. Virtual function is an example of dynamic polymorphism.
 Static polymorphism is also known as early binding and compile-time
polymorphism.
 Dynamic polymorphism is also known as late binding and run-time
polymorphism.

 Function Overloading : Function overloading is an example of static


polymorphism. More than one function with same name, with different signature
in a class or in a same scope is called function overloading.
 Operator Overloading : Another example of static polymorphism is Operator
overloading. Operator overloading is a way of providing new implementation of
existing operators to work with user-defined data types.
 Virtual function : Virtual function is an example of dynamic polymorphism.
Virtual function is used in situation, when we need to invoke derived class
function using base class pointer. Giving new implementation of derived class
method into base class and the calling of this new implemented function with
base class's object is done by making base class function as virtual function. This
is how we can achieve "Runtime Polymorphism".

Pointers to Objects
A variable that holds an address value is called a pointer variable or simply pointer.
Pointer can point to objects as well as to simple data types and arrays.
sometimes we dont know, at the time that we write the program , how many objects we want to creat.
when this is the case we can use new to creat objects while the program is running. new returns a
pointer to an unnamed objects. lets see the example of student that wiil clear your idea about this topic

#include <iostream>
#include <string>
using namespace std;
class student
{
private:
int rollno;
string name;
public:
student():rollno(0),name("")
{}
student(int r, string n): rollno(r),name (n)
{}
void get()
{
cout<<"enter roll no";
cin>>rollno;
cout<<"enter name";
cin>>name;
}
void print()
{
cout<<"roll no is "<<rollno;
cout<<"name is "<<name;
}
};
void main ()
{
student *ps=new student;
(*ps).get();
(*ps).print();
delete ps;
}

‘this’ pointer in C++


To understand ‘this’ pointer, it is important to know how objects look at functions and
data members of a class.

1. Each object gets its own copy of the data member.


2. All-access the same function definition as present in the code segment.

Meaning each object gets its own copy of data members and all objects share a single
copy of member functions.
Then now question is that if only one copy of each member function exists and is used
by multiple objects, how are the proper data members are accessed and updated?
The compiler supplies an implicit pointer along with the names of the functions as ‘this’.
The ‘this’ pointer is passed as a hidden argument to all nonstatic member function calls
and is available as a local variable within the body of all nonstatic functions. ‘this’ pointer
is not available in static member functions as static member functions can be called
without any object (with class name).
For a class X, the type of this pointer is ‘X* ‘. Also, if a member function of X is declared
as const, then the type of this pointer is ‘const X *’ (see this GFact)
In the early version of C++ would let ‘this’ pointer to be changed; by doing so a
programmer could change which object a method was working on. This feature was
eventually removed, and now this in C++ is an r-value.

C++ lets object destroy themselves by calling the following code :


delete this;

As Stroustrup said ‘this’ could be the reference than the pointer, but the reference was
not present in the early version of C++. If ‘this’ is implemented as a reference then, the
above problem could be avoided and it could be safer than the pointer.
Following are the situations where ‘this’ pointer is used:
1) When local variable’s name is same as member’s name
#include<iostream>
using namespace std;

/* local variable is same as a member's name */


class Test
{
private:
int x;
public:
void setX (int x)
{
// The 'this' pointer is used to retrieve the object's x
// hidden by the local variable 'x'
this->x = x;
}
void print() { cout << "x = " << x << endl; }
};

int main()
{
Test obj;
int x = 20;
obj.setX(x);
obj.print();
return 0;
}
Output:
x = 20
For constructors, initializer list can also be used when parameter name is same as
member’s name.

2) To return reference to the calling object


/* Reference to the calling object can be returned */
Test& Test::func ()
{
// Some processing
return *this;
}
When a reference to a local object is returned, the returned reference can be used
to chain function calls on a single object.
#include<iostream>
using namespace std;

class Test
{
private:
int x;
int y;
public:
Test(int x = 0, int y = 0) { this->x = x; this->y = y; }
Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};

int main()
{
Test obj1(5, 5);

// Chained function calls. All calls modify the same object


// as the same object is returned by reference
obj1.setX(10).setY(20);

obj1.print();
return 0;
}
Output:
x = 10 y = 20

Exercise:
Predict the output of following programs. If there are compilation errors, then fix them.
Question 1
#include<iostream>
using namespace std;

class Test
{
private:
int x;
public:
Test(int x = 0) { this->x = x; }
void change(Test *t) { this = t; }
void print() { cout << "x = " << x << endl; }
};

int main()
{
Test obj(5);
Test *ptr = new Test (10);
obj.change(ptr);
obj.print();
return 0;
}
Question 2
#include<iostream>
using namespace std;

class Test
{
private:
int x;
int y;
public:
Test(int x = 0, int y = 0) { this->x = x; this->y = y; }
static void fun1() { cout << "Inside fun1()"; }
static void fun2() { cout << "Inside fun2()"; this->fun1(); }
};

int main()
{
Test obj;
obj.fun2();
return 0;
}
Question 3
#include<iostream>
using namespace std;

class Test
{
private:
int x;
int y;
public:
Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};

int main()
{
Test obj1;
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
#include<iostream>
using namespace std;

class Test
{
private:
int x;
int y;
public:
Test(int x = 0, int y = 0) { this->x = x; this->y = y; }
void setX(int a) { x = a; }
void setY(int b) { y = b; }
void destroy() { delete this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};

int main()
{
Test obj;
obj.destroy();
obj.print();
return 0;
}

POINTER TO DERIVED CLASS

In C++, we can declare a pointer points to the base class as well as derive class.
Consider below example to understand pointer to derived class
#include<iostream.h>

class base

public:

int n1;

void show()

cout<<”\nn1 = “<<n1;

};

class derive : public base


{

public:

int n2;

void show()

cout<<”\nn1 = “<<n1;

cout<<”\nn2 = “<<n2;

};

int main()

base b;

base *bptr; //base pointer

cout<<”Pointer of base class points to it”;


bptr=&b; //address of base class
bptr->n1=44; //access base class via base pointer

bptr->show();

derive d;

cout<<”\n”;
bptr=&d; //address of derive class
bptr->n1=66; //access derive class via base pointer

bptr->show();
return 0;

}
Output
Pointer of base class points to it

n1 = 44
Pointer of base class points to derive class

n1=66
Here the show() method is the overridden method, bptr execute show() method of ‘base’ class twice and
display its content. Even though bptr first points to ‘base’ and second time points to ‘derive’ ,both the time
bptr->show() executes the ‘base’ method show()

C++ Virtual Function


In this article, you will learn about virtual function and where to use it. Also,
you will learn about pure virtual function and abstract class.

A virtual function is a member function in base class that you expect to


redefine in derived classes.

Before going into detail, let's build an intuition on why virtual functions are
needed in the first place.

An Example to Begin With


Let us assume, we are working on a game (weapons specifically).

We created the Weapon class and derived two classes Bomb and Gun to load
features of respective weapons.

#include <iostream>
using namespace std;

class Weapon
{
public:
void loadFeatures()
{ cout << "Loading weapon features.\n"; }
};

class Bomb : public Weapon


{
public:
void loadFeatures()
{ cout << "Loading bomb features.\n"; }
};

class Gun : public Weapon


{
public:
void loadFeatures()
{ cout << "Loading gun features.\n"; }
};

int main()
{
Weapon *w = new Weapon;
Bomb *b = new Bomb;
Gun *g = new Gun;

w->loadFeatures();
b->loadFeatures();
g->loadFeatures();

return 0;
}

Output

Loading weapon features.


Loading bomb features.
Loading gun features.

We defined three pointer objects w , b and g of


classes Weapon , Bomb and Gun respectively. And, we
called loadFeatures() member function of each objects using:

w->loadFeatures();
b->loadFeatures();

g->loadFeatures();

Works perfectly!

However, our game project started getting bigger and bigger. And, we decided
to create a separate Loader class to load weapon features.
This Loader class loads additional features of a weapon depending on which
weapon is selected.

class Loader
{
public:
void loadFeatures(Weapon *weapon)
{
weapon->features();
}
};

The loadFeatures() loads the feature of a specific weapon.


Let's try to implement our Loader class

#include <iostream>
using namespace std;
class Weapon {
public:
Weapon() { cout << "Loading weapon features.\n"; }

void features() { cout << "Loading weapon features.\n"; }


};
class Bomb : public Weapon {
public:
void features() {
this->Weapon::features();
cout << "Loading bomb features.\n";
}
};
class Gun : public Weapon {
public:
void features() {
this->Weapon::features();
cout << "Loading gun features.\n";
}
};
class Loader {
public:
void loadFeatures(Weapon *weapon) {
weapon->features();
}
};
int main() {
Loader *l = new Loader;
Weapon *w;
Bomb b;
Gun g;
w = &b;
l->loadFeatures(w);
w = &g;
l->loadFeatures(w);
return 0;
}

Output

Loading weapon features.


Loading weapon features.
Loading weapon features.
Loading weapon features.

Our implementation seemed correct. However, weapon features were loaded


4 times. Why?

Initially, the Weapon object w is pointing to the b object (of Bomb) class. And,
we tried to load the features of Bomb object by passing it
to loadFeatures() function using l object to pointer (of Loader class).
Similarly, we tried to load the features of Gun object.
However, the loadFeatures() function of the Loader class takes pointer to object
of a Weapon class as an argument:

void loadFeatures(Weapon *weapon)

That's the reason weapon features are loaded 4 times. To solve this issue, we
need to make function of base class ( Weapon class) virtual using virtual
keyword.

class Weapon
{
public:
virtual void features()
{ cout << "Loading weapon features.\n"; }
};

Example: Using Virtual Function to Solve the Problem

#include <iostream>
using namespace std;

class Weapon
{
public:
virtual void features()
{ cout << "Loading weapon features.\n"; }
};

class Bomb : public Weapon


{
public:
void features()
{ this->Weapon::features();
cout << "Loading bomb features.\n";
}
};

class Gun : public Weapon


{
public:
void features()
{
this->Weapon::features();
cout << "Loading gun features.\n";
}
};

class Loader
{
public:
void loadFeatures(Weapon *weapon)
{
weapon->features();
}
};

int main()
{
Loader *l = new Loader;
Weapon *w;
Bomb b;
Gun g;

w = &b;
l->loadFeatures(w);

w = &g;
l->loadFeatures(w);

return 0;
}

Output

Loading weapon features.


Loading bomb features.
Loading weapon features.
Loading gun features.
Also, notice that, the l->loadFeatures(w) function calls the function of different
classes depending upon what l object is pointing.
Using virtual function made our code not only clearer but flexible too.

In the above program, weapon features is printed twice. We encourage you to


add additional code on the above program to load weapon features only once.

If we want to add another weapon (let's say knife), we can easily add and load
features of it. How?

class Knife : public Weapon


{
public:
void features()
{
this->Weapon::features();
cout << "Loading knife features.\n";
}
};

And, in main() function.

Knife k;

w = &k;

l->loadFeatures(w);

It's worth noticing that we didn't change anything in the Loader class to load
features of knife.

C++ Abstract class and Pure virtual Function


The goal of object-oriented programming is to divide a complex problem into
small sets. This helps understand and work with problem in an efficient way.

Sometimes, it's desirable to use inheritance just for the case of better
visualization of the problem.

In C++, you can create an abstract class that cannot be instantiated (you
cannot create object of that class). However, you can derive a class from it
and instantiate object of the derived class.

Abstract classes are the base class which cannot be instantiated.

A class containing pure virtual function is known as abstract class.

Pure Virtual Function Example: Using Virtual Function


to Solve the Problem

#include <iostream>
using namespace std;

class Weapon
{
public:
virtual void features()
{ cout << "Loading weapon features.\n"; }
};

class Bomb : public Weapon


{
public:
void features()
{ this->Weapon::features();
cout << "Loading bomb features.\n";
}
};

class Gun : public Weapon


{
public:
void features()
{
this->Weapon::features();
cout << "Loading gun features.\n";
}
};

class Loader
{
public:
void loadFeatures(Weapon *weapon)
{
weapon->features();
}
};

int main()
{
Loader *l = new Loader;
Weapon *w;
Bomb b;
Gun g;

w = &b;
l->loadFeatures(w);

w = &g;
l->loadFeatures(w);

return 0;
}

Output

Loading weapon features.


Loading bomb features.
Loading weapon features.
Loading gun features.

Also, notice that, the l->loadFeatures(w) function calls the function of different
classes depending upon what l object is pointing.
Using virtual function made our code not only clearer but flexible too.

In the above program, weapon features is printed twice. We encourage you to


add additional code on the above program to load weapon features only once.

If we want to add another weapon (let's say knife), we can easily add and load
features of it. How?

class Knife : public Weapon


{
public:
void features()
{
this->Weapon::features();
cout << "Loading knife features.\n";
}
};

And, in main() function.

Knife k;

w = &k;

l->loadFeatures(w);

It's worth noticing that we didn't change anything in the Loader class to load
features of knife.
C++ Abstract class and Pure virtual Function
The goal of object-oriented programming is to divide a complex problem into
small sets. This helps understand and work with problem in an efficient way.

Sometimes, it's desirable to use inheritance just for the case of better
visualization of the problem.

In C++, you can create an abstract class that cannot be instantiated (you
cannot create object of that class). However, you can derive a class from it
and instantiate object of the derived class.

Abstract classes are the base class which cannot be instantiated.

A class containing pure virtual function is known as abstract class.

Pure Virtual Function


A virtual function whose declaration ends with =0 is called a pure virtual
function. For example,

class Weapon

public:

virtual void features() = 0;

};

Here, the pure virtual function is


virtual void features() = 0

And, the class Weapon is an abstract class.

Example: Abstract Class and Pure Virtual Function

#include <iostream>
using namespace std;

// Abstract class
class Shape
{
protected:
float l;
public:
void getData()
{
cin >> l;
}

// virtual Function
virtual float calculateArea() = 0;
};

class Square : public Shape


{
public:
float calculateArea()
{ return l*l; }
};

class Circle : public Shape


{
public:
float calculateArea()
{ return 3.14*l*l; }
};

int main()
{
Square s;
Circle c;

cout << "Enter length to calculate the area of a square: ";


s.getData();
cout<<"Area of square: " << s.calculateArea();
cout<<"\nEnter radius to calculate the area of a circle: ";
c.getData();
cout << "Area of circle: " << c.calculateArea();

return 0;
}

Output

Enter length to calculate the area of a square: 4


Area of square: 16
Enter radius to calculate the area of a circle: 5
Area of circle: 78.5

In this program, pure virtual function virtual float area() = 0; is defined inside
the Shape class.
One important thing to note is that, you should override the pure virtual
function of the base class in the derived class. If you fail the override it, the
derived class will become an abstract class as well.

You might also like