Virtual String Function problem

So here is my very long (I apologize) list of classes. There are two things I need to do

1. Create the virtual string function whatami() for the Person class. The function returns the type of class - Person, Faculty, Staff, etc. Note that you must create a separate function for each derivedclass.
2. Write a string function classify which accepts a Person pointer variable as an argument and returns the output from whatami().

Can anyone help, it would be greatly appreciated. Thank you in advance

#include <string>
using namespace std;

class Person
{
public:

Person();
Person(string n, string a, string t, string e)
string getName();
string getAddress();
string getTelephone();
string getEmail();
virtual string whatami() {

private:

string name;
string address;
string telephone;
string email;
};

Person::Person()
{
name = "default_name";
address = "default_address";
telephone = "default_phone";
email = "default_email";
}

Person::Person(string n, string a, string t, string e)
{
name = n;
address = a;
telephone = t;
email = e;
}

string Person::getName()
{
return name;
}

string Person::getAddress()
{
return address;
}

string Person::getTelephone()
{
return telephone;
}

string Person::getEmail()
{
return email;
}

class Student : public Person
{
public:
Student();
Student(string n, string a, string t, string e, string s);
string getStatus();
private:
string status;
};

Student::Student()
:Person()
{
status = "default_status";
}

Student::Student(string n, string a, string t, string e, string s)
:Person(n,a,t,e)
{
status = s;
}

string Student::getStatus()
{
return status;
}

class Employee : public Person
{
public:
Employee();
Employee(string n, string a, string t, string e, string o, string w, string h);
string getOffice();
string getWages();
string getHired();

private:
string office;
string wages;
string hired;
};

Employee::Employee()
:Person()
{
office = "default_office";
wages = "default_wages";
hired = "default_hired";
}

Employee::Employee(string n, string a, string t, string e, string o, string w, string h)
:Person(n,a,t,e)
{
office = o;
wages = w;
hired = h;
}

string Employee::getOffice()
{
return office;
}

string Employee::getWages()
{
return wages;
}

string Employee::getHired()
{
return hired;
}

class Faculty : public Employee
{
public:
Faculty();
Faculty(string n, string a, string t, string e, string o, string w, string h, string r, string s);
string getRank();
string getStatus();

private:
string rank;
string status;
};

Faculty::Faculty()
:Employee()
{
rank = "default_rank";
status = "default_status";
}

Faculty::Faculty(string n, string a, string t, string e, string o, string w, string h, string r, string s)
:Employee(n,a,t,e,o,w,h)
{
rank = r;
status = s;
}

string Faculty::getRank()
{
return rank;
}

string Faculty::getStatus()
{
return status;
}


class Staff : public Employee
{
public:
Staff();
Staff(string n, string a, string t, string e, string o, string w, string h, string p);
string getPosition();

private:
string position;
};

Staff::Staff()
:Employee()
{
position = "default_position";
}

Staff::Staff(string n, string a, string t, string e, string o, string w, string h, string p)
:Employee(n,a,t,e,o,w,h)
{
position = p;
}

string Staff::getPosition
{
return position;
}

class StaffST : public Student, public Staff
{
public:
StaffST();
StaffST(string n, string a, string t, string e, string o, string w, string h, string p, int c)
int getCreditHours();

private:
int credithours;
};

StaffST::StaffST()
:Student, Staff
{
credithours = "default_credithours";
}

StaffST::StaffST(string n, string a, string t, string e, string o, string w, string h, string p, int c)
:Student(n,a,t,e,s), Staff(n,a,t,e,o,w,h,p)
{
credithours = c;
}

int StaffST::getCreditHours()
{
return credithours;
}
What specifically are you having problems with. At first glance I see that you haven't written your derived class' whatami() methods.

What don't you know how to do?
This looks like an assignment from the same class I am in and I am having trouble as well.

1. Create a new class StaffST which has Staff and Student as base classes. StaffSt has an additional attribute (int) credithours.
2. Create the virtual string function whatami() for the Person class. The function returns the type of class - Person, Faculty, Staff, etc. Note that you must create a separate function for each derivedclass.
3. Write a string function classify which accepts a Person pointer variable as an argument and returns the output from whatami().
4. Write a test main program that creates a vector of pointers to Person. Creat a Person, Student, Employee, Faculty, Staff and StaffST object and add pointers to these objects to your vector. Now use the function classify to output the type of each object from the vector pointers.

I am having trouble with a couple of things:
In part 1 I get " error: ‘Person’ is an ambiguous base of ‘StaffST’ "
I think I got part 2 but since I cannot seem to figure out how to create the classify function I cannot check that
In part 3 I have no idea how or where to write the classify function so any help would be appreciated

This is my code:

#ifndef PERSON_H
#define PERSON_H
#include <string>
using namespace std;

class Person{
public:
Person();
Person(string n, string a, string p, string e);
string getname(){return name;}
string getaddress(){return address;}
string getphone(){return phone;}
string getemail(){return email;}
virtual string whatami(){return "Person";}
private:
string name;
string address;
string phone;
string email;
};

Person::Person(){
name = "name";
address = "address";
phone = "phone";
email = "email";
}

Person::Person(string n, string a, string p, string e){
name = n;
address = a;
phone = p;
email = e;
}
#endif


#ifndef STUDENT_H
#define STUDENT_H
#include "Person.h"
#include <string>
using namespace std;

class Student : public Person{
public:
Student();
Student(string n, string a, string p, string e, string i, string y);
string getid(){return id;}
string getyear(){return year;}
virtual string whatami(){return "Student";}
private:
string id;
string year;
};

Student::Student():Person(){
id = "id";
year = "year";
}

Student::Student(string n, string a, string p, string e, string i, string y):Person(n, a, p, e){
id = i;
year = y;
}
#endif


#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include "Person.h"
#include <string>
using namespace std;

class Employee : public Person{
public:
Employee();
Employee(string n, string a, string p, string e, string o, string s, string h);
string getoffice(){return office;}
string getsalary() {return salary;}
string gethiredate() {return hiredate;}
virtual string whatami(){return "Employee";}
private:
string office;
string salary;
string hiredate;
};

Employee::Employee():Person(){
office = "office";
salary = "salary";
hiredate = "hiredate";
}

Employee::Employee(string n, string a, string p, string e, string o, string s, string h):Person(n, a, p, e){
office = o;
salary = s;
hiredate = h;
}
#endif


#ifndef STAFF_H
#define STAFF_H
#include "Person.h"
#include "Employee.h"
#include <string>
using namespace std;

class Staff : public Employee{
public:
Staff();
Staff(string n, string a, string p, string e, string o, string s, string h, string pos);
string getposition(){return position;}
virtual string whatami(){return "Staff";}
private:
string position;
};

Staff::Staff(){
position = "position";
}

Staff::Staff(string n, string a, string p, string e, string o, string s, string h, string pos):Employee(n, a, p, e, o, s, h){
position = pos;
}
#endif


#ifndef FACULTY_H
#define FACULTY_H
#include "Person.h"
#include "Employee.h"
#include <string>
using namespace std;

class Faculty : public Employee{
public:
Faculty();
Faculty(string n, string a, string p, string e, string o, string s, string h, string r, string st);
string getrank(){return rank;}
string getstatus(){return status;}
virtual string whatami(){return "Faculty";}
private:
string rank;
string status;
};

Faculty::Faculty():Employee(){
rank = "rank";
status = "status";
}

Faculty::Faculty(string n, string a, string p, string e, string o, string s, string h, string r, string st):Employee(n, a, p, e, o, s, h){
rank = r;
status = st;
}
#endif


#ifndef STAFFST_H
#define STAFFST_H
#include "Person.h"
#include "Student.h"
#include "Employee.h"
#include "Staff.h"
#include <string>
using namespace std;

class StaffST : public Student, public Staff{
public:
StaffST();
StaffST(string n, string a, string p, string e, string i, string y, string o, string s, string h, string pos, int ch);
int getcredithours(){return credithours;}
virtual string whatami(){return "StaffST";}
private:
int credithours;
};

StaffST::StaffST(){
credithours = 0;
}

StaffST::StaffST(string n, string a, string p, string e, string i, string y, string o, string s, string h, string pos, int ch):Student(n, a, p, e, i, y),Staff(n, a, p, e, o, s, h, pos){
credithours = ch;
}
#endif


int main(){

vector<Person*> v;
v.push_back(new Person("John Adams","Boston","617-555-0000","[email protected]"));
v.push_back(new Student("John Quincy Adams","Boston","617-555-0000","[email protected]","0098765","senior"));
v.push_back(new Employee("John Smith","Boston","617-555-0000","[email protected]","brewhouse 2","1000","9-15-1759"));
v.push_back(new Staff("Samuel Adams","Boston","617-555-BEER","[email protected]","brewhouse 1","1000","9-15-1764","Brewer"));
v.push_back(new Faculty("John Samuel Adams","Boston","617-555-BEER","[email protected]","brewhouse 3","1000","9-15-1769","Assistant","Brewer"));
v.push_back(new StaffST("John Adams Smith","Boston","617-555-BEER","[email protected]","0012345","junior","brewhouse 5","100","9-15-1774","Taster",15));

for (int i=0; i<v.size(); i++){
cout << classify(v[i]) << endl;
cout << "Name: " << v[i]->getname() << endl;
cout << "Address: " << v[i]->getaddress() << endl;
cout << "Phone: " << v[i]->getphone() << endl;
cout << "Email: " << v[i]->getemail() << endl;
if(classify(v[i]) == "Student"){
cout << "ID: " << v[i]->getid() << endl;
cout << "Year: " << v[i]->getyear() << endl;
}
if(classify(v[i]) == "Employee"){
cout << "Office: " << v[i]->getoffice() << endl;
cout << "Salary: " << v[i]->getsalary() << endl;
cout << "Hire Date: " << v[i]->gethiredate() << endl;
if(classify(v[i]) == "Staff"){
cout << "Position: " <<v[i]->getposition() << endl;
}
if(classify(v[i]) == "Faculty"){
cout << "Rank: " << v[i]->getrank() << endl;
cout << "Staff: " << v[i]->getstaff() << endl;
}
}
if(classify(v[i]) == "StaffST"){
cout << "Credit Hours: " << v[i]->getcredithours() << endl;
}
cout << endl;
}

return 1;
}
I'm still new to this. But to get around the ambiguity I think it has something to do with declaring whether you want it to use Staff's or Student's Person.
like if its
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   StaffST ss("StaffST","2034 Work Way","961 229 1292","[email protected]","008382976", "Junoir","129k","10,000","01/02/2011","Janitorial",37);
   cout << ss.whatami() << ": " << endl;

   cout << "Name: " << ss.getname() << endl;
   cout << "Address: " << ss.getaddress() << endl;
   cout << "Phone: " << ss.getphone() << endl;
   cout << "Email: " << ss.getemail() << endl;

   cout << "Office: " << ss.getoffice() << endl;
   cout << "Salary: " << ss.getsalary() << endl;
   cout << "Hire Date: " << ss.gethiredate() << endl;
   cout << "Position: " << ss.getposition() << endl;
   cout << "ID: " << ss.getid() << endl;
   cout << "Year: " << ss.getyear() << endl;
   cout << "Credithours: " << ss.getcredithours()<< endl <<endl;


Instead you want like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   StaffST ss("StaffST","2034 Work Way","961 229 1292","[email protected]","008382976", "Junoir","129k","10,000","01/02/2011","Janitorial",37);
   cout << ss.whatami() << ": " << endl;

   cout << "Name: " << ss.Staff::getname() << endl;  //notice the Staff::
   cout << "Address: " << ss.Staff::getaddress() << endl;
   cout << "Phone: " << ss.Staff::getphone() << endl;
   cout << "Email: " << ss.Staff::getemail() << endl;

   cout << "Office: " << ss.getoffice() << endl;
   cout << "Salary: " << ss.getsalary() << endl;
   cout << "Hire Date: " << ss.gethiredate() << endl;
   cout << "Position: " << ss.getposition() << endl;
   cout << "ID: " << ss.getid() << endl;
   cout << "Year: " << ss.getyear() << endl;
   cout << "Credithours: " << ss.getcredithours()<< endl <<endl;


Actually, the more correct option here would be to use virtual inheritance to avoid the multiple base classes.
I got it thank you for your help
I tried the virtual inheritance, but would get a run time error. I couldn't find much that explained how to implement the virtual inheritance well. Like I said I'm new to c++ so I was probably doing something off.
All I really had to do was add

1
2
3

virtual string whatami();


to each class.

The member function was then, (change Person to each class accordingly)

1
2
3
4
5
6

string Person::whatami()
{
 return Person;
}
Last edited on
Topic archived. No new replies allowed.