C++ Object-Oriented Programming: Virtual Functions, Abstract Classes, and Operator Overloading

Experiment Objectives

  1. Understand base class and derived class definitions and usage.
  2. Learn declaration and usage of virtual functions and pure virtual functions.
  3. Master definition and usage of abstract classes.
  4. Familiarize with fundamental methods of operator overloading.

Experiment Tasks

Task 1

Enter, compile, and run the following program. Analyze the output and explain each line.

#include<iostream>
using namespace std;

class Vehicle {
public:
    Vehicle(int speed = 60)
        : _speed(speed) {
    }
    
    virtual void Display() {
        cout << "Vehicle speed: " << _speed << endl;
    }
    
    int _speed;
};

class Car : public Vehicle {
public:
    Car(int speed = 80)
        : _wheelCount(4), Vehicle(speed) {
    }
    
    void Display() override {
        cout << "Car wheel count: " << _wheelCount << endl;
    }
    
    int _wheelCount;
};

int main() {
    Vehicle v1;
    Car c1;
    Vehicle* ptr = &v1;
    ptr->Display();
    ptr = &c1;
    ptr->Display();
    return 0;
}

Output

Vehicle speed: 60
Car wheel count: 4

This experiment demonstrates runtime polymorphism through virtual functions. The base class pointer calls different implementations based on the actual object type.

Task 2

Enter, compile, and run the following program. Analyze the output and explain each line.

#include<iostream>
using namespace std;

const double PI = 3.14159;

class Shape {
public:
    virtual double computeArea() = 0;
    virtual ~Shape() {}
};

class Circle : public Shape {
public:
    Circle(double r) : radius(r) {}
    
    double computeArea() override {
        return PI * radius * radius;
    }
    
    bool operator==(const Circle& other) const {
        return radius == other.radius;
    }
    
private:
    double radius;
};

class Cylinder : public Circle {
public:
    Cylinder(double r, double h) : Circle(r), height(h) {}
    
    double computeArea() override {
        return 2.0 * PI * radius * (height + radius);
    }
    
private:
    double height;
};

int main() {
    Shape* shapePtr;
    Circle circle1(5), circle2(5);
    
    shapePtr = &circle1;
    cout << "Circle area with radius 5: " << shapePtr->computeArea() << endl;
    
    Cylinder cylinder(3, 7);
    shapePtr = &cylinder;
    cout << "Cylinder area with radius 3 and height 7: " 
         << shapePtr->computeArea() << endl;
    
    if (circle1 == circle2) {
        cout << "Both circles have equal radius" << endl;
    } else {
        cout << "Circles have different radius" << endl;
    }
    
    return 0;
}

Output

Circle area with radius 5: 78.5397
Cylinder area with radius 3 and height 7: 188.496
Both circles have equal radius

This program demonstrates abstract classes with pure virtual functions and operator overloading. The Shape class cannot be instantiated directly, serving as a blueprint for derived classes.

Task 3

A company calculates employee monthly salaries using base pay plus bonus. Managers receive $8000 base pay with $100 per project. Supervisors receive $5000 base pay with $60 per project. Regular employees receive $3000 base pay with $30 per project. Define an abstract Employee class, derive different position classes, and calcluate monthly salaries for multiple employees (assume one manager has 15 projects, one supervisor has 25 projects, and one regular employee has 40 projects).

#include<iostream>
using namespace std;

class Employee {
protected:
    int projectCount;
    
public:
    Employee(int projects) : projectCount(projects) {}
    virtual int calculateSalary() = 0;
    virtual ~Employee() {}
};

class Manager : public Employee {
public:
    Manager(int projects) : Employee(projects) {}
    
    int calculateSalary() override {
        return 8000 + 100 * projectCount;
    }
};

class Supervisor : public Employee {
public:
    Supervisor(int projects) : Employee(projects) {}
    
    int calculateSalary() override {
        return 5000 + 60 * projectCount;
    }
};

class RegularEmployee : public Employee {
public:
    RegularEmployee(int projects) : Employee(projects) {}
    
    int calculateSalary() override {
        return 3000 + 30 * projectCount;
    }
};

int main() {
    Employee* staff[3];
    staff[0] = new Manager(15);
    staff[1] = new Supervisor(25);
    staff[2] = new RegularEmployee(40);
    
    for (int i = 0; i < 3; ++i) {
        cout << "Employee " << (i + 1) << " monthly salary: $" 
             << staff[i]->calculateSalary() << endl;
    }
    
    for (int i = 0; i < 3; ++i) {
        delete staff[i];
    }
    
    return 0;
}

Output

Employee 1 monthly salary: $9500
Employee 2 monthly salary: $6500
Employee 3 monthly salary: $4200

This implementation uses polymorphism to calculate different salary structures through a unified interface. The abstract base class ensures each derived class implements its own salary calculation logic.

Tags: C++ Object-Oriented Programming Virtual Functions abstract classes Operator Overloading

Posted on Tue, 30 Jun 2026 16:44:57 +0000 by benutne