Programming with C++ - Day5 || Wong Edition || B.Tech Diaries

Lab #5 - Inheritance and Over-Riding

Question 1 - Company Hierarchy

In a Company Hierarchy consisting of Clerk, Manager and Director, the invoice approval limits are as follows:-

  • Clerk - $100
  • Manager - $500
  • Director - $1000

The UML Class Diagram for the Clerk is as shown.

Clerk
- name : String
- designation: String
* getName : String
* getDesignation : String
* introduce() : String
* approveInvoice(in invoiceAmount:double) : boolean
  • Depict the Company Hierarchy in a UML Class Diagram.
  • Implement the Company Hierarchy. Over-Ride the approveInvoice function to ensure the approval limits are adhered to. [Hint: create the main() loop in the Director class and create instances of Clerk, Manager and Director]

Solution:


#include <iostream>

/**
    * @brief Class Clerk
*/
class Clerk
{
private:
    std::string name, designation;

public:
    Clerk(std::string);
    Clerk(std::string, std::string);
    ~Clerk();
    std::string getName();
    std::string getDesignation();
    std::string introduce();
    bool approveInvoice(double);
};

Clerk::Clerk(std::string name)
{
    this->name = name;
    this->designation = "Clerk";
}

Clerk::Clerk(std::string name, std::string designation)
{
    this->name = name;
    this->designation = designation;
}

Clerk::~Clerk()
{
}

std::string Clerk::getName()
{
    return this->name;
}

std::string Clerk::getDesignation()
{
    return this->designation;
}

std::string Clerk::introduce()
{
    return "My name is " + this->name + " and I am a " + this->designation;
}

bool Clerk::approveInvoice(double amount)
{
    if (amount <= 100)
        return true;
    else
        return false;
}

/**
    * @brief Class Manager
*/

class Manager : public Clerk
{
private:
public:
    Manager(std::string);
    Manager(std::string, std::string);
    ~Manager();
    bool approveInvoice(double);
};

Manager::Manager(std::string name) : Clerk(name, "Manager")
{
}

Manager::Manager(std::string name, std::string designation) : Clerk(name, designation)
{
}

Manager::~Manager()
{
}

bool Manager::approveInvoice(double amount)
{
    if (amount <= 500)
        return true;
    else
        return false;
}

/**
    * @brief Class Manager
*/

class Director : public Manager
{
private:
public:
    Director(std::string);
    ~Director();
    bool approveInvoice(double);
};

Director::Director(std::string name) : Manager(name, "Director")
{
}

Director::~Director()
{
}

bool Director::approveInvoice(double amount)
{
    if (amount <= 1000)
        return true;
    else
        return false;
}

// program 1
int main(int argc, char const *argv[])
{
    Clerk clerk("John");
    Manager manager("Jane");
    Director director("Jack");

    std::cout << clerk.introduce() << std::endl;
    std::cout << manager.introduce() << std::endl;
    std::cout << director.introduce() << std::endl;

    std::cout << (clerk.approveInvoice(77) ? "True" : "False") << std::endl;
    std::cout << (clerk.approveInvoice(100) ? "True" : "False") << std::endl;
    std::cout << (clerk.approveInvoice(124) ? "True" : "False") << std::endl;

    std::cout << (manager.approveInvoice(427) ? "True" : "False") << std::endl;
    std::cout << (manager.approveInvoice(500) ? "True" : "False") << std::endl;
    std::cout << (manager.approveInvoice(584) ? "True" : "False") << std::endl;

    std::cout << (director.approveInvoice(927) ? "True" : "False") << std::endl;
    std::cout << (director.approveInvoice(1000) ? "True" : "False") << std::endl;
    std::cout << (director.approveInvoice(1084) ? "True" : "False") << std::endl;
    return 0;
}    

Output:


My name is John and I am a Clerk
My name is Jane and I am a Manager
My name is Jack and I am a Director
True
True
False
True
True
False
True
True
False

Question 2 - Company Hierarchy with Outsourcing

To cut costs, the Company decided to take on Contractors.

A Contractor has a Name in the company records, but has no formal designation. A Contractor cannot approveInvoice (but of course!).

Suppose that at a Company function, everyone has to introduce himself / herself:-

    Hello, my name is xxx.  My designation is XXX.
                          or
    Hello, my name is yyy.  I am a Contractor.
  • Design the new Company Hierarchy in a UML Class Diagram, to accommodate the Contractor. [Hint: pull up the common attributes / properties and behaviour into an Abstract Class.]
  • Implement the new Company Hierarchy. Keep the main() loop in the Director class.

Solution:


...
// program 2

class Contractor : protected Clerk
{
private:

public:
    Contractor(std::string);
    ~Contractor();
    std::string introduce();
    std::string getName();
};

Contractor::Contractor(std::string name) : Clerk(name)
{
}

Contractor::~Contractor()
{
}

std::string Contractor::introduce()
{
    return "My name is " + this->getName() + " and I am a Contractor";
}

std::string Contractor::getName()
{
    return Clerk::getName();
}

int main(int argc, char const *argv[])
{
    Contractor contractor("John");
    std::cout << contractor.introduce() << std::endl;
    std::cout << contractor.getName() << std::endl;

    return 0;
}


My name is John and I am a Contractor
John

Question 3 - Fraud!

Suppose a Director in the Company tries to impersonate his Clerk at the Company function by introducing himself as a Clerk. By using casting, show how that this is possible.


Clerk* cPtr = new Manager(...);
cPtr->introduce();   

Suppose a Clerk in the Company tries to impersonate his Manager at the Company function. Explain why this is not possible.


Manager* mPtr = new Clerk(...);
mPtr->introduce();

Solution:


...
// program 3
int main(int argc, char const *argv[])
{
    Clerk *cPtr = new Manager("John");
    std::cout << cPtr->introduce() << std::endl;

    try
    {
        Manager *mPtr = new Clerk("Jane");
        mPtr->introduce();
    }
    catch (const std::exception &e)
    {
        std::cerr << e.what() << 'n';
    }

    return 0;
}


My name is John and I am a Manager

Share:

Programming with C++ - Day4 || Wong Edition || B.Tech Diaries

Lab #4 - Overloading

Question 1 - Employee

Create an Employee class according to the given Class Diagram.


Employee
- name: String
- gender: int
- colour : string
- Employee()
* Employee(in_name:String, in_gender:boolean)
- getName(): String
- getGender(): boolean
- print(): String

The default constructor is declared private to prevent its use. boolean getGender() returns FALSE if male and TRUE if female. The print() function gives the following sample output:

    Hello, my name is Arif. I am male.

From 2014, India officially recognises a third gender. Modify your design (i.e. give a new UML Class Diagram) to provide

    an overloaded constructor to take in gender information as an integer,
    an overloaded getGender() function that returns 0 if male, 1 if female and -1 if transgender, and
    an overloaded print() function that handles the third gender. 

In your main() loop, create

    2 Employee instances, hired before 2014, and
    3 Employee instances, hired after 2014.

Solution:


#include <iostream>
#include <sstream>

class Employee
{
private:
    std::string name;
    int gender;
    Employee();

public:
    Employee(std::string, bool);
    Employee(std::string, int);
    ~Employee();
    std::string getName();
    bool getGender();
    int getGender(int);
    std::string print();
    std::string print(int);
};

Employee::Employee()
{
}

Employee::~Employee()
{
}

Employee::Employee(std::string name, bool gender)
{
    this->name = name;
    this->gender = gender;
}

std::string Employee::getName()
{
    return name;
}

bool Employee::getGender()
{
    return gender;
}

std::string Employee::print()
{
    std::stringstream ps;
    ps << "Hello, my name is " << name << ". I am " << (gender == 0 ? "male" : "female") << "." << std::endl;
    return ps.str();
}

/*
    After 2014 changes
*/

Employee::Employee(std::string name, int gender)
{
    this->name = name;
    this->gender = gender;
}

int Employee::getGender(int i)
{
    if (i)
        return this->getGender();
    return gender;
}

std::string Employee::print(int i)
{
    if (i)
        this->print();

    std::stringstream ps;
    ps << "Hello, my name is " << name << ". I am " << (gender == 0 ? "male" : (gender == 1 ? "female" : "transgender")) << "." << std::endl;
    return ps.str();
}

int main(int argc, char const *argv[])
{
    Employee e1("Alpha", false), e2("Beta", true);
    std::cout << e1.print(0);
    std::cout << e2.print(0);
    Employee em1("Delta", 1), em2("Gamma", 0), em3("Epsilon", -1);
    std::cout << em1.print(0);
    std::cout << em2.print(0);
    std::cout << em3.print(0);
    return 0;
}    

Output:


Hello, my name is Alpha. I am male.
Hello, my name is Beta. I am female.
Hello, my name is Delta. I am female.
Hello, my name is Gamma. I am male.
Hello, my name is Epsilon. I am transgender.

Question 2 - Operator Overloading

Implement a class named RealTime with representation HH:MM:SS. Design and implement appropriate constructors.

Overload the following operators:

    +	 Addition e.g. myRealTime + yourRealTime
    ++	 Post-Increment e.g. myRealTime++
    ++	 Pre-Increment e.g. ++RealTime 

Provide comments in your code and proper indentation, so that it is easy to read.

Solution:


#include <iostream>
#include <iomanip>

class RealTime
{
private:
    int hr, min, sec;

public:
    RealTime();
    RealTime(int, int, int);
    ~RealTime();
    RealTime operator+(RealTime const &);
    RealTime operator++();
    RealTime operator++(int);
    friend std::ostream &operator<<(std::ostream &, RealTime const &);
};

RealTime::RealTime()
{
    hr = min = sec = 0;
}

RealTime::RealTime(int hr, int min, int sec)
{
    this->hr = hr;
    this->min = min;
    this->sec = sec;
}

RealTime::~RealTime()
{
}

RealTime RealTime::operator+(RealTime const &rt)
{
    RealTime temp;
    temp.sec = this->sec + rt.sec;
    temp.min = this->min + rt.min + temp.sec / 60;
    temp.sec %= 60;
    temp.hr = this->hr + rt.hr + temp.min / 60;
    temp.min %= 60;
    return temp;
}

RealTime RealTime::operator++()
{
    ++sec;
    min = min + sec / 60;
    sec %= 60;
    hr = hr + min / 60;
    min %= 60;
    return *this;
}

RealTime RealTime::operator++(int)
{
    RealTime temp(hr, min, sec);
    sec++;
    min = min + sec / 60;
    sec %= 60;
    hr = hr + min / 60;
    min %= 60;
    return temp;
}

std::ostream &operator<<(std::ostream &os, RealTime const &rt)
{
    return os << std::setfill('0') << std::setw(2) << rt.hr << ":"
                << std::setfill('0') << std::setw(2) << rt.min << ":"
                << std::setfill('0') << std::setw(2) << rt.sec;
}

int main(int argc, char const *argv[])
{
    RealTime myRealTime(7, 2, 5), yourRealTime(12, 34, 56);
    RealTime resRealTime = myRealTime + yourRealTime;
    std::cout << "My Real Time = " << myRealTime << std::endl;
    std::cout << "Your Real Time = " << yourRealTime << std::endl;
    std::cout << "Total Real Time = " << resRealTime << std::endl;
    std::cout << "Prefix Add Real Time = " << ++myRealTime << std::endl;
    std::cout << "Postfix Add Real Time = " << yourRealTime++ << std::endl;
    std::cout << yourRealTime << std::endl;
    return 0;
}    

Output:


My Real Time = 07:02:05
Your Real Time = 12:34:56
Total Real Time = 19:37:01
Prefix Add Real Time = 07:02:06
Postfix Add Real Time = 12:34:56
12:34:57

Share:

Programming with C++ - Day3 || Wong Edition || B.Tech Diaries

Lab #3 - Classes

Question 1 - Rectangle

Implement the Rectangle class according to the given Class Diagram.

Rectangle
- length : int
- width: int
- colour : string
+ getArea() : int
+ print() : string
+ compare(Rectangle r1) : int

Write a constructor which takes as input the length and width of a Rectangle instance. In the default constructor, initalise the length and width to 0;

The function compare returns

    0, if the Rectangle instances are of the same size,
    1, if r1 is larger
    -1, if r1 is smaller 

The function print gives the dimensions, colour and area of the Rectangle instance.

In the main function of Rectangle, obtain and validate user input for the Rectangle's dimensions and colour. Create 2 Rectangle instances and compare their area. [Hint: check for type and negative numbers]

Solution:


    #include <iostream>
    #include <sstream>

    class Rectangle
    {
    private:
        int length, breadth;
        std::string colour;

    public:
        Rectangle();
        Rectangle(int, int, std::string);
        ~Rectangle();
        int getArea();
        std::string print();
        int compare(Rectangle);
    };

    Rectangle::Rectangle()
    {
        length = 0;
        breadth = 0;
        colour = "";
    }

    Rectangle::Rectangle(int length, int breadth, std::string colour)
    {
        this->length = length;
        this->breadth = breadth;
        this->colour = colour;
    }

    Rectangle::~Rectangle()
    {
    }

    int Rectangle::getArea()
    {
        return this->length * this->breadth;
    }

    std::string Rectangle::print()
    {
        std::stringstream ps;
        ps << "nLength: " << this->length
        << "nBreadth: " << this->breadth
        << "nColour: " << this->colour
        << "nArea: " << this->getArea() << std::endl;
        return ps.str();
    }

    int Rectangle::compare(Rectangle rect)
    {
        if (this->getArea() > rect.getArea())
            return 1;
        else if (this->getArea() < rect.getArea())
            return -1;
        return 0;
    }

    int main(int argc, char const *argv[])
    {
        int len, br;
        std::string col;

        // std::cout << "Enter dimensions for Rectangle 1:n"
        //           << "Length:";
        while (std::cin >> len)
        {
            if (len > 0)
                break;
            if (len <= 0)
                std::cout << "Length should be greater than 0n";
        }
        // std::cout << "Breadth:";
        while (std::cin >> br)
        {
            if (br > 0)
                break;
            if (br <= 0)
                std::cout << "Breadth should be greater than 0" << std::endl;
        }
        // std::cout << "Color:";
        std::cin.ignore();
        std::cin >> col;
        Rectangle rect1(len, br, col);

        // std::cout << "Enter dimensions for Rectangle 2:n"
        //           << "Length:";
        while (std::cin >> len)
        {
            if (len > 0)
                break;
        }
        // std::cout << "Breadth:";
        while (std::cin >> br)
        {
            if (br > 0)
                break;
        }
        // std::cout << "Color:";
        std::cin.ignore();
        std::cin >> col;
        Rectangle rect2(len, br, col);

        std::cout << "Rectangle 1n"
                << rect1.print() << std::endl;
        std::cout << "Rectangle 2n"
                << rect2.print() << std::endl;

        if (rect1.compare(rect2) == 1)
            std::cout << "Rectangle 1 is bigger than Rectangle 2" << std::endl;
        else if (rect1.compare(rect2) == -1)
            std::cout << "Rectangle 2 is bigger than Rectangle 1" << std::endl;
        else
            std::cout << "Rectangle 1 and Rectangle 2 are equal" << std::endl;

        return 0;
    }  

Output:


    12
    54
    Red
    24
    32
    Green
  
    Rectangle 1
    
    Length: 12
    Breadth: 54
    Colour: Red
    Area: 648
    
    Rectangle 2
    
    Length: 24
    Breadth: 32
    Colour: Green
    Area: 768
    
    Rectangle 2 is bigger than Rectangle 1

Question 2 - Student Records

In a UML Diagram, design a Student class with the following attributes:-

    name (max 30 characters)
    rollNumber (between 1 and 260)
    mobileNumber (10 digits)
    emailAddress (must contain '@' and then '.')
    attendance (between 0 and 1, where 1 is 100% attendance)

Provide the following functions:-

    getName, getRollNumber, ...
    setName, setRollNumber, ...
    print, which outputs the Student details in a comma-delimited string

    e.g. Donald Duck, 123, 1234567890, donald@duck.com, 0.00

The Student records are managed by the StudentManager class, which holds the main() loop.

StudentManager
- studentList:Student[10]
* getStudentInput:Student
* sortByRollNumber:Student[]
* sortByAttendance:Student[]
* printAttendanceReport(filename, sortBy:bool) : bool

The function printAttendanceReport outputs the list of students to a user-specified filename. If sortBy is true, the student list will be sorted by roll number, else the student list will be sorted by attendance (followed by roll number).

Provide the following user menu:

  1. Enter Student Details
  2. Update Student Mobile Number
  3. Update Student Email Address
  4. Print Attendance Report by Roll Number
  5. Print Attendance Report by Attendance
  6. Exit

Solution:


#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>

class Student
{
private:
    std::string name;
    int rollNumber;

public:
    long mobileNumber;
    std::string emailAddress;
    double attendance;

    Student();
    ~Student();
    std::string getName();
    int getRollNumber();
    void setName(std::string);
    void setRollNumber(int);
    std::string print();
};

Student::Student()
{
    this->name = "";
    this->rollNumber = 0;
    this->mobileNumber = 0;
    this->emailAddress = "";
    this->attendance = 0;
}

Student::~Student()
{
}

std::string Student::getName()
{
    return name;
}

int Student::getRollNumber()
{
    return rollNumber;
}

void Student::setName(std::string name)
{
    this->name = name;
}

void Student::setRollNumber(int rollNumber)
{
    this->rollNumber = rollNumber;
}

std::string Student::print()
{
    std::stringstream ps;
    ps << name << "," << rollNumber << "," << mobileNumber << "," << emailAddress << "," << attendance;
    return ps.str();
}

class StudentManager
{
private:
    std::vector<Student> studentList;

public:
    StudentManager();
    ~StudentManager();
    Student getStudentInput();
    void addStudent(Student);
    bool isEmpty();
    Student getStudent(int);
    bool setStudent(int, Student);
    std::vector<Student> sortByRollNumber();
    std::vector<Student> sortByAttendance();
    bool printAttendanceReport(std::string, bool);
};

StudentManager::StudentManager()
{
}

StudentManager::~StudentManager()
{
}

void StudentManager::addStudent(Student student)
{
    studentList.push_back(student);
}

Student StudentManager::getStudent(int rollno)
{
    for (int i = 0; i < studentList.size(); i++)
    {
        if (studentList[i].getRollNumber() == rollno)
        {
            return studentList[i];
        }
    }
    return Student();
}

bool StudentManager::setStudent(int rollno, Student student)
{
    for (int i = 0; i < studentList.size(); i++)
    {
        if (studentList[i].getRollNumber() == rollno)
        {
            studentList[i] = student;
            return true;
        }
    }
    return false;
}

bool StudentManager::isEmpty()
{
    return studentList.empty();
}

Student StudentManager::getStudentInput()
{
    Student student;
    std::string name;
    int rollNumber;
    long mobileNumber;
    std::string emailAddress;
    double attendance;
    std::cout << "Enter name: ";
    std::cin.ignore();
    std::getline(std::cin, name);
    std::cout << "Enter roll number: ";
    std::cin >> rollNumber;
    std::cout << "Enter mobile number: ";
    std::cin >> mobileNumber;
    std::cout << "Enter email address: ";
    std::cin.ignore();
    std::cin >> emailAddress;
    std::cout << "Enter attendance: ";
    std::cin >> attendance;
    student.setName(name);
    student.setRollNumber(rollNumber);
    student.mobileNumber = mobileNumber;
    student.emailAddress = emailAddress;
    student.attendance = attendance;
    return student;
}

std::vector<Student> StudentManager::sortByRollNumber()
{
    int N = this->studentList.size();
    std::vector<Student> studentList(N);
    for (int i = 0; i < N; i++)
    {
        studentList[i] = this->studentList[i];
    }
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N - i - 1; j++)
        {
            if (studentList[j].getRollNumber() > studentList[j + 1].getRollNumber())
            {
                std::swap(studentList[j], studentList[j + 1]);
            }
        }
    }
    return studentList;
}

std::vector<Student> StudentManager::sortByAttendance()
{
    int N = this->studentList.size();
    std::vector<Student> studentList(N);
    for (int i = 0; i < N; i++)
    {
        studentList[i] = this->studentList[i];
    }
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N - i - 1; j++)
        {
            if (studentList[j].attendance > studentList[j + 1].attendance)
            {
                std::swap(studentList[j], studentList[j + 1]);
            }
            else if ((studentList[j].attendance == studentList[j + 1].attendance) && (studentList[j].getRollNumber() > studentList[j + 1].getRollNumber()))
            {
                std::swap(studentList[j], studentList[j + 1]);
            }
        }
    }
    return studentList;
}

bool StudentManager::printAttendanceReport(std::string filename, bool sortBy)
{
    std::ofstream report;
    report.open(filename);

    std::vector<Student> studentList;

    if (sortBy)
    {
        studentList = sortByRollNumber();
    }
    else
    {
        studentList = sortByAttendance();
    }

    for (Student stud : studentList)
    {
        report << stud.print() << std::endl;
    }

    report.close();

    return true;
}

int main(int argc, char const *argv[])
{
    StudentManager mngr;
    int ch = 0;
    int rollNumber;
    Student stud;
    std::string filename;

    while (ch != 5)
    {
        std::cout << "n======Student Manager======" << std::endl;
        std::cout << "0.  Enter Student Detailsn"
                  << "1.  Update Student Mobile Numbern"
                  << "2.  Update Student Email Addressn"
                  << "3.  Print Attendance Report by Roll Numbern"
                  << "4.  Print Attendance Report by Attendancen"
                  << "5.  Exitn"
                  << std::endl;
        std::cout << "Enter your choice: ";
        std::cin >> ch;

        switch (ch)
        {
        case 0:
            mngr.addStudent(mngr.getStudentInput());
            break;
        case 1:
            if (mngr.isEmpty())
            {
                std::cout << "No students entered yet"
                          << std::endl;
                break;
            }
            std::cout << "Enter roll number: ";
            std::cin >> rollNumber;
            stud = mngr.getStudent(rollNumber);
            if (stud.getRollNumber() == 0)
            {
                std::cout << "Student not found"
                          << std::endl;
                break;
            }
            std::cout << "Enter Mobile number: ";
            std::cin >> stud.mobileNumber;
            mngr.setStudent(rollNumber, stud);
            break;
        case 2:
            if (mngr.isEmpty())
            {
                std::cout << "No students entered yet"
                          << std::endl;
                break;
            }
            std::cout << "Enter roll number: ";
            std::cin >> rollNumber;
            stud = mngr.getStudent(rollNumber);
            if (stud.getRollNumber() == 0)
            {
                std::cout << "Student not found"
                          << std::endl;
                break;
            }
            std::cout << "Enter Email address: ";
            std::cin.ignore();
            std::cin >> stud.emailAddress;
            mngr.setStudent(rollNumber, stud);
            break;

        case 3:
            if (mngr.isEmpty())
            {
                std::cout << "No students entered yet"
                          << std::endl;
                break;
            }

            std::cout << "Enter filename: ";
            std::cin.ignore();
            std::getline(std::cin, filename);
            mngr.printAttendanceReport(filename, true);
            break;

        case 4:
            if (mngr.isEmpty())
            {
                std::cout << "No students entered yet"
                          << std::endl;
                break;
            }

            std::cout << "Enter filename: ";
            std::cin.ignore();
            std::getline(std::cin, filename);
            mngr.printAttendanceReport(filename, false);
            break;

        case 5:
            std::cout << "Exiting..." << std::endl;
            break;

        default:
            std::cout << "Invalid choice" << std::endl;
            break;
        }
    }

    return 0;
}

Output:


    ======Student Manager======
    0.  Enter Student Details
    1.  Update Student Mobile Number
    2.  Update Student Email Address
    3.  Print Attendance Report by Roll Number
    4.  Print Attendance Report by Attendance
    5.  Exit
    
    Enter your choice: 0
    Enter name: Bhola
    Enter roll number: 45
    Enter mobile number: 32
    Enter email address: bholaeatschola@gmail.com
    Enter attendance: 78
    
    ======Student Manager======
    0.  Enter Student Details
    1.  Update Student Mobile Number
    2.  Update Student Email Address
    3.  Print Attendance Report by Roll Number
    4.  Print Attendance Report by Attendance
    5.  Exit
    
    Enter your choice: 3
    Enter filename: report
    
    ======Student Manager======
    0.  Enter Student Details
    1.  Update Student Mobile Number
    2.  Update Student Email Address
    3.  Print Attendance Report by Roll Number
    4.  Print Attendance Report by Attendance
    5.  Exit
    
    Enter your choice: 5
    Exiting...

File Contents:

Bhola,45,32,bholaeatschola@gmail.com,78
Share: