Lab 8

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 9

NOV 19,

2022

COMPUTER
PROGRAMMING

LAB 7
NIMRAH BANO

MOHAMMAD ALI JINNAH UNIVERSITY


Lab Instructor Ms. Nimrah Bano
Course Computer Programming Lab
Duration 3hrs

Objectives:

 In this lab, following topics will be covered


 Virtual Destructors
 Abstract Classes

What are Abstract Classes in C++?


Sometimes implementation of all function cannot be provided in a base class because we don’t
know the implementation. Such a class is called abstract class.  An abstract class contains at least
one pure virtual function. For example, let Shape be a base class. We cannot provide
implementation of function draw() in Shape, but we know every derived class must have
implementation of draw(). Similarly an Animal class doesn’t have implementation of move()
(assuming that all animals move), but all animals must know how to move. We cannot create
objects of abstract classes.
A pure virtual function (or abstract function) in C++ is a virtual function for which we can have
implementation, But we must override that function in the derived class, otherwise the derived class
will also become abstract class.
A pure virtual function is declared by assigning 0 in declaration. See the following example. 

// An abstract class

class Test

{   

    // Data members of class

public:

    // Pure Virtual Function

    virtual void show() = 0;


    

   /* Other members */

};

A pure virtual function is implemented by classes which are derived from a Abstract class.
Following is a simple example to demonstrate the same.

#include<iostream>
using namespace std;

class Base
{
int x;
public:
virtual void fun() = 0;
int getX() { return x; }
};

// This class inherits from Base and implements fun()


class Derived: public Base
{
int y;
public:
void fun() { cout << "fun() called"; }
};

int main(void)
{
Derived d;
d.fun();
return 0;
}

Output:

fun() called

#include
using namespace std;
class Test
{
int x;
public:
virtual void show() = 0;
int getX() { return x; }
};
int main(void)
{
Test t;
return 0;
}
Output:

Compiler Error: cannot declare variable’t’ to be of abstract Type 'Test' because the following virtual
functions are pure Within 'Test': note: virtual void Test::show ()

We can have pointers and references of abstract class type. For example the following program works
fine.

#include<iostream>
using namespace std;

class Base
{
public:
virtual void show() = 0;
};

class Derived: public Base


{
public:
void show() { cout << "In Derived \n"; }
};

int main(void)
{
Base *bp = new Derived();
bp->show();
return 0;
}

Output:
In Derived
If we do not override the pure virtual function in derived class, then derived class also becomes abstract
class. 
The following example demonstrates the same.  

#include<iostream>
using namespace std;
class Base
{
public:
virtual void show() = 0;
};

class Derived : public Base { };

int main(void)
{
Derived d;
return 0;
}

Output:
Compiler Error: cannot declare variable’d’ to be of abstract type ‘Derived’ because the following
virtual functions are pure within 'Derived': virtual void Base::show ()

// C++ program to calculate the area of a square and a circle

#include <iostream>
using namespace std;

// Abstract class
class Shape {
protected:
float dimension;

public:
void getDimension() {
cin >> dimension;
}
// pure virtual Function
virtual float calculateArea() = 0;
};

// Derived class
class Square : public Shape {
public:
float calculateArea() {
return dimension * dimension;
}
};

// Derived class
class Circle : public Shape {
public:
float calculateArea() {
return 3.14 * dimension * dimension;
}
};

int main() {
Square square;
Circle circle;

cout << "Enter the length of the square: ";


square.getDimension();
cout << "Area of square: " << square.calculateArea() << endl;

cout << "\nEnter radius of the circle: ";


circle.getDimension();
cout << "Area of circle: " << circle.calculateArea() << endl;

return 0;
}
Output:

Enter the length of the square: 4


Area of square: 16

Enter radius of the circle: 5


Area of circle: 78.5

In this program, virtual float calculateArea() = 0; inside the Shape class is a pure virtual function.

That's why we must provide the implementation of calculateArea() in both of our derived classes, or else

we will get an error.

Virtual Destructors
A virtual destructor is used to free up the memory space allocated by the derived class object or instance
while deleting instances of the derived class using a base class pointer object. A base or parent class
destructor use the virtual keyword that ensures both base class and the derived class destructor will be
called at run time, but it called the derived class first and then base class to release the space occupied by
both destructors.

Deleting a derived class object using a pointer of base class type that has a non-virtual destructor
results in undefined behavior. To correct this situation, the base class should be defined with a virtual
destructor. For example, following program results in undefined behavior . 

// CPP program without virtual destructor


// causing undefined behavior
#include <iostream>
 
using namespace std;
 
class base {
  public:
    base()    
    { cout << "Constructing base\n";
}
    ~base()
    { cout<< "Destructing base\n"; }    
};
 
class derived: public base {
  public:
    derived()    
     { cout << "Constructing derived\n"; }
    ~derived()
       { cout << "Destructing derived\n"; }
};
 
int main()
{
  derived *d = new derived(); 
  base *b = d;
  delete b;
  getchar();
  return 0;
}

Output:
Constructing base
Constructing derived
Destructing base

Making base class destructor virtual guarantees that the object of derived class is destructed properly,
i.e., both base class and derived class destructors are called. For example, 

#include <iostream>
 
using namespace std;
 
class base {
  public:
    base()    
    { cout << "Constructing base\n"; }
    virtual ~base()
    { cout << "Destructing base\n"; }    
};
 
class derived : public base {
  public:
    derived()    
    { cout << "Constructing derived\n"; }
    virtual ~derived()
    { cout << "Destructing derived\n"; }
};
 
int main()
{
  derived *d = new derived(); 
  base *b = d;
  delete b;
  getchar();
  return 0;
}

Output:
Constructing base
Constructing derived
Destructing derived
Destructing base

You might also like