3
// Homework 3.cpp : Defines the entry point for the console application.
//

#include <iostream>
#include <string>
#include <iomanip>
#include <cassert>

using namespace std;

class Person{
public:
    Person(){ //Default Constructor
        name = "";
        ssn = 0;
        age = 0;
        gender = "";
        address = "";
        phone = "";
    }

    Person(const Person& p){ //copy constructor
        name = p.name;
        ssn = p.ssn;
        age = p.age;
        gender = p.gender;
        address = p.address;
        phone = p.phone;
    }

    Person(string _name, int _ssn, int _age, string _gender, string _address, string _phone)
    {
        name = _name;
        ssn = _ssn;
        age = _age;
        gender = _gender;
        address = _address;
        phone = _phone;
    }

    const string getName(){ return name; }
    const int getSSN(){ return ssn; }
    const int getAge(){ return age; }
    const string getGender(){ return gender; }
    const string getAddress(){ return address; }
    const string getPhone(){ return phone; }

    void setName(const string name);
    void setSSN(const int ssn);
    void setAge(const int age);
    void setGender(const string gender);
    void setAddress(const string address);
    void setPhone(const string phone);

protected:
    string name;
    int ssn;
    int age;
    string gender;
    string address;
    string phone;

};

class Student : public Person{
public:
    Student(){ //default
        gpa = 0;
        major = "";
        gradYear = 0;
    }

    Student(const Student& s) //copy
    {
        gpa = s.gpa;
        major = s.major;
        gradYear = s.gradYear;
    }

    Student(string _name, int _ssn, int _age, string _gender, string _address, string _phone, double _gpa, string _major, int _gradYear) : Person(_name, _ssn, _age, _gender, _address, _phone){
        gpa = _gpa;
        major = _major;
        gradYear = _gradYear;
    }


    const double getGPA(){ return gpa; }
    const string getMajor(){ return major; }
    const int getGradYear(){ return gradYear; }

    void setGPA(const double gpa);
    void setMajor(const string major);
    void setGradYear(const int gradYear);

protected:
    double gpa;
    string major;
    int gradYear;
};

class Employee : public Person{
public:
    Employee(){
        department = "";
        jobTitle = "";
        yearHire = 0;
    }

    Employee(const Employee& e){
        department = e.department;
        jobTitle = e.jobTitle;
        yearHire = e.yearHire;
    }

    Employee(string _name, int _ssn, int _age, string _gender, string _address, string _phone, string _department, string _jobTitle, int _yearHire) : Person(_name, _ssn, _age, _gender, _address, _phone){
        department = _department;
        jobTitle = _jobTitle;
        yearHire = _yearHire;
    }

    const string getDepartment(){ return department; }
    const string getJobTitle(){ return jobTitle; }
    const int getYearHire(){ return yearHire; }

    void setDepartment(const double department);
    void setJobTitle(const double jobTitle);
    void setYearHire(const double yearHire);


    virtual double getAnnualWages() = 0; // a pure virtual function.

protected:
    string department;
    string jobTitle;
    int yearHire;
};

class HourlyEmployee : public Employee{
public:
    HourlyEmployee(){
        hourlyRate = 0;
        hoursWorked = 0;
        unionDues = 0;

    }

    HourlyEmployee(const HourlyEmployee& he){
        hourlyRate = he.hourlyRate;
        hoursWorked = he.hoursWorked;
        unionDues = he.unionDues;
    }

    HourlyEmployee(string _name, int _ssn, int _age, string _gender, string _address, string _phone, string _department, string _jobTitle, int _yearHire, double _hourlyRate, double _hoursWorked, double _unionDues):Employee(_name, _ssn, _age, _gender, _address, _phone, _department, _jobTitle, _yearHire){
        hourlyRate = _hourlyRate;
        hoursWorked = _hoursWorked;
        unionDues = _unionDues;
    }

    const double getHourlyRate(){ return hourlyRate; }
    const double getHoursWorked(){ return hoursWorked; }
    const double getUnionDues(){ return unionDues; }

    void setHourlyRate(const double hourlyRate);
    void setHoursWorked(const double hoursWorked);
    void setUnionDues(const double unionDues);

    double getAnnualWages(){ return (hourlyRate*hoursWorked) + unionDues; }

protected:
    double hourlyRate;
    double hoursWorked;
    double unionDues;

};

class SalariedEmployee : public Employee{
public:
    SalariedEmployee(){ annualSalary = 0; }

    SalariedEmployee(const SalariedEmployee& se){
        annualSalary = se.annualSalary;
    }

    SalariedEmployee(string _name, int _ssn, int _age, string _gender, string _address, string _phone, string _department, string _jobTitle, int _yearHire, double _annualSalary):Employee(_name, _ssn, _age, _gender, _address, _phone, _department, _jobTitle, _yearHire)
    {
        annualSalary = _annualSalary;
    }

    double getAnnualSalary(){ return annualSalary; }

    void setAnnualSalary(const double annualSalary);

    double getAnnualWages(){ return annualSalary; }

protected:
    double annualSalary;

};

class StudentEmployee : public Student, public HourlyEmployee{ //multiple inheritance of student and HourlyEmployee
public:


    StudentEmployee(){}

    StudentEmployee(const StudentEmployee& ste){}

    StudentEmployee(string _name, int _ssn, int _age, string _gender, string _address, string _phone, string _department, string _jobTitle, int _yearHire, double _hourlyRate, double _hoursWorked, double _unionDues,double _gpa, string _major, int _gradYear): Student(_name, _ssn, _age, _gender, _address, _phone, _gpa, _major, _gradYear), HourlyEmployee(_name, _ssn, _age, _gender, _address, _phone, _department, _jobTitle, _yearHire, _hourlyRate, _hoursWorked, _unionDues){}



protected:
};

struct ListNode { //struct for list
    Person p;
    ListNode *link;
};

class SingleLinkedList{ //class to store all persons
public:
    SingleLinkedList() {
        front = rear = nullptr;
        size = 0;
    }

    ~SingleLinkedList() {
        Clear();
    }

    ListNode* headptr(){
        return front;
    }

    // Removes every node in the list.  Frees my memory with delete.
    void Clear() {
        ListNode *node = front;

        while (node != nullptr) {
            ListNode *next = node->link;
            delete node;
            node = next;
        }

        front = rear = nullptr;
        size = 0;
    }

    bool Contains(Person p) const {
        ListNode *node = front;

        while (node != nullptr) {
            if ( node->p.getName() == p.getName() && node->p.getSSN() == p.getSSN() && node->p.getAge() == p.getAge() && node->p.getGender() == p.getGender() && node->p.getAddress() == p.getAddress() && node->p.getPhone() == p.getPhone() ) { return true; } //checks to see if all of the information for the person is the same
            node = node->link;
        }

        return false;
    }

    void PopFront() {
        assert(size > 0);

        ListNode *obsolete = front;

        if (front == rear) { // Exactly one element in our list
            front = rear = nullptr;
        }
        else {
            front = obsolete->link;
        }

        delete obsolete;
        --size;
    }

    void PushBack(Person p) {
        ListNode *insert = new ListNode(); // We need to delete this node later
        insert->p = p;
        insert->link = nullptr;

        if (front == nullptr) {
            front = rear = insert;
        }

        rear->link = insert;
        rear = insert;
        ++size;
    }

    void PushFront(Person p) {
        ListNode *insert = new ListNode();
        insert->link = front; // This node will be the new front, connect the old front
        insert->p = p;

        if (front == nullptr) {  // No elements currently in the list
            front = rear = insert;
        }

        front = insert;
        ++size;
    }

    int Size() const {
        return size;
    }

    void displayNode(ListNode *ptr)const{
        cout << setw(3) << ptr->p.getName() << endl;
    }

    void displayList(ListNode *ptr)const{
        if (ptr==nullptr){
            cout << "Nothing to display!\n";
        }
        for (int i = 1; i <= size;i++){
            displayNode(ptr);
            ptr = ptr->link;
        }
    }

protected:
    int size;
    ListNode *front, *rear; // Front points to first node in list, rear to last
};








//main program
int main()
{
    Person a("John Doe", 123456789, 26, "male", "123 Park Pl", "555-123-4567");
    Person b("Jane Smith", 234567890, 21, "female", "66 Oak Ave", "123-456-7890");
    Student s("Katie Brown",749374394, 18,"female","100 Curtain Rd","472-473-2038", 4.0, "Statistics", 2016);
    SalariedEmployee se("Ross Gellar", 123056789, 55, "male", "123 5th Ave", "515-683-8924", "Science", "Professor", 1999, 50000);
    HourlyEmployee he("Monica Bing", 123056589, 55, "female", "64 South Park Dr", "538-238-0747", "Dining", "Chef", 1999, 20.00, 40, 100);
    StudentEmployee stuem("Cathrine Miller", 550789234, 25, "female", "218 Knickerbocker Way", "888-555-0000", "Fitness", "Trainer", 2015, 7.25, 10, 5, 3.2, "Computer Science", 2017);


    SingleLinkedList x;
    x.PushBack(a);
    x.PushBack(b);
    x.PushFront(s); //adds student f to the list of persons
    x.displayList(x.headptr());

    if (x.Contains(a) == true) //to show john doe is on list
        cout << "This " << a.getName() << " is in the list.\n";
    else
        cout << "This " << a.getName() << " is NOT in the list.\n";

    x.Clear(); //clears list

    x.displayList(x.headptr());

    if (x.Contains(a) == true) //shows john doe not on list because list was cleared
        cout << "This " << a.getName() << " is in the list.\n";
    else
        cout << "This " << a.getName() << " is NOT in the list.\n";


    cout<< "Annual Wages for "<<se.getName()<<" is "<<se.getAnnualWages()<<endl;
    cout<< "Annual Wages for "<<he.getName()<<" is "<<he.getAnnualWages()<<endl;
    cout<< "Annual Wages for "<<stuem.getName()<<" is "<<stuem.getAnnualWages()<<endl;


    return 0;
}

on the last cout statement, my program will give me the error message non-static member 'getName' found in multiple base-class subobjects of type person. i know i have to refer all the variables to just one of the base classes, but i dont know how to

xenaluke
  • 41
  • 1
  • 3
  • this is the diamond problem: studentEmployee has 2 distinct inheritance paths to getName. one via studentEmployee->student->person and another via studentEmployee->hourlyEmployee->Employee->person – ForeverStudent Dec 11 '15 at 16:31

1 Answers1

4

You have to use virtual inheritance from Person in this case. I guess that's the point of this homework. You're encountering The Diamond problem, because at stuem.getName(), the compiler doesn't know which instance of the two underlying Person base class instances to use.

Making the inheritance virtual will insure, that there's only one Person object:

class Student : virtual public Person { ... };
class Employee : virtual public Person { ... };

Off topic, but by this time you should be using member initialization lists and assigning "" to std::string which is already initialized and empty is, well, uncomfortable to look at. And copy-constructors can be defaulted in C++11:

Person(const Person& p) = default;
Community
  • 1
  • 1
LogicStuff
  • 19,397
  • 6
  • 54
  • 74
  • 3
    It's important to keep in mind, though, that the decision to use a virtual base is driven by the **design** of the hierarchy, not by a desire to fix compiler errors. It's appropriate here because a `StudentEmployee` is only one `Person`. There are other situations where a base class occurs more thane once **by design** and making it virtual would be a mistake. – Pete Becker Dec 11 '15 at 16:48