how to make Inheritance dependence - c++

I'm triying to make this exercise:
There are different types of employees: regular
workers,supervisors,board members which are specific types of
supervisors
Track the number of objects of type regular worker.
Each employee has its name and surname and can introduce himself.
Each employee object has its own worker id which is assigned to him
while it is created
The salary is calculated is specific way depending on the type of the
employee.
Each employee can have its direct supervisor which can be any
supervisor(it means that for example a board member can be a
supervisor of regular worker)
Now i had made all of point, exclude the last point:
class Employees
{
public:
static int workerid;
int salary;
Employees(){
workerid += 1;
}
void introduce(){
cout << "the name is:" << name << "and surname" << surname << endl;
}
};
int Employees::workerid = 0;
class Supervisors :public Employees{
public:
Supervisors(){
salary = 1000;
}
};
class BoardMembers : public Supervisors{
public:
BoardMembers(){
salary = 1200;
}
};
class RegularWorkers :public Employees{
public:
static int number;
Supervisors *supervisor;
RegularWorkers(Supervisors supervisor){
this->supervisor = &supervisor;
number += 1;
salary = 600;
}
};
int RegularWorkers::number = 0;
(i think until the last point is ok), but for the last point I need one id of the supervisor but how to made the supervisor or boardemember assign to the regularworker?
Thank you & best regards

Modify the employee class by adding a Supervisor
Supervisor *supervisor;
And then overload the Employee constructor to accept type Supervisor and set them equal to each other.
Employees(Supervisor *s){
supervisor = s;
workerid += 1;
}
Then you can access the Supervisor's ID by using
supervisor->ID
Also you may want to include name and surname as member variables and initialize those as well in the constructor. To add to the previous constructor it might look like this.
Employees(Supervisor *s, string sName, string sSurname){
name = sName;
surname = sSurname;
supervisor = s;
workerid += 1;
}

Related

OOP problem related to default constructor having setter from cin and pointer to object doesn't return the name

I have 3 fields,one void method to return minimum price,constructor with 3 parameters and a getter for name.
a) First I need to create an instance for this constructor and to return the name and the minimum price which I did.
b) Secondly I need to create a default constructor(so no parameters) and a setter method to set the fields but from the keyboard.
c) In the end I need to do the same thing as at a) but by using a pointer.
My problem is:
I don't know how to make b) cuz the setter doesn't work and when I try to return the name of the pointer object from c) it doesn't show anyting
#include <iostream>
using namespace std;
class CTest{
private:
string name;
float price1;
float price2;
public:
CTest(string name,float price1,float price2){
this->name = name;
this->price1 = price1;
this->price2 = price2;
}
CTest(){};
void set_values(string name,float price1,float price2){
cin>>name;
cin>>price1;
cin>>price2;
}
string get_name(){
return name;
}
void minimum_price() {
if(this->price1 < this->price2)
cout<<"Min price is " <<this->price1;
else
cout<<"Min price is " <<this->price2;
}
};
int main(){
CTest P ("Phone",450.9f,500.9f);
cout<<P.get_name();
cout<<endl;
P.minimum_price();
CTest *A = new CTest("Something",4.5f,3.5f);
cout<<A->get_name();
cout<<endl;
A->minimum_price();
return 0;
}
So this is wrong
void set_values(string name,float price1,float price2){
cin>>name;
cin>>price1;
cin>>price2;
}
because the three parameters hide the names of the your class member variables. So the values from cin go to the parameters not to your class.
What you probably meant is this
void set_values(){
cin>>name;
cin>>price1;
cin>>price2;
}
Now the values from cin will go to your class.

Losing a data member of a base class after the constructor is called

I have been working on a project and had no problems until today where I lost a class data member after the constructor is called. I could not pinpoint where the change happens. I have several classes for cars. The classes related to the cars are in the code block below. After all the cars are created in the class RegistrationSystem they are stored in an array. however, while calling a display function in RegistrationSystem the first car loses the color value. In the class RegistrationSystem the first Pickup in the class stores the value until the constructor is complete. After the constructor ends, the color value string shows " " in the debugger.
class Car {
protected:
string color;
public:
Car(string c) { color = c; };
string getColor(void) { return color; }
friend ostream& operator<<(ostream& outStream, const Car& car) {
cout << car.color;
return outStream;
}
};
class Pickup : public Car {
public:
Seat *frontSeat = new Seat(FRONT_SEAT_CREDIT);
Pickup(string c) : Car(c) {}
};
class Compact : public Car {
public:
Seat *frontSeat = new Seat(FRONT_SEAT_CREDIT);
Seat *sideBackLeftSeat = new Seat(BACK_SEAT_COMPACT_CREDIT);
Seat *sideBackRightSeat = new Seat(BACK_SEAT_COMPACT_CREDIT);
Compact(string c) : Car(c) {}
};
class Sedan : public Car {
public:
Seat *frontSeat = new Seat(FRONT_SEAT_CREDIT);
Seat *sideBackLeftSeat = new Seat(SIDE_BACK_SEDAN_CREDIT);
Seat *sideBackRightSeat = new Seat(SIDE_BACK_SEDAN_CREDIT);
Seat *middleBackSeat = new Seat(MID_BACK_SEDAN_CREDIT);
Sedan(string c) : Car(c) {}
};
class RegistrationSystem {
private:
string file_name;
int menu_response;
Reservation *reservations[24] = { NULL };
Passenger *rowers[24];
Pickup *pickup_cars[3];
Compact *compact_cars[3];
Sedan *sedan_cars[3];
// Displays the Layouts
void displaySeatArrangements(void);
// Saves the information in the file
void saveToFile(void);
// Find the rower in array rowers
Passenger* findRower(string);
// Displays the menu for the seat choice of a car type
bool displayCarSeatingChoiceMenu(string);
// Make a reservation in the system
bool makeReservation(string, string, int, Passenger&);
// Delete a reservation
bool deleteReservation(int);
// Print Reservations
void saveReservationsToFile(void);
// Sub functions for makeReservation()
bool makePickupReservation(Pickup*, Passenger, int&, string, string);
bool makeCompactReservation(Compact*, Passenger, int&, string, string);
bool makeSedanReservation(Sedan*, Passenger, int&, string, string);
public:
RegistrationSystem(void);
void chooseOperation(void);
Passenger* getPassengers(void) { return *rowers; }
friend ostream& operator<<(ostream&, const RegistrationSystem&);
friend istream& operator>>(istream&, RegistrationSystem&);
};
The display function has a line:
<< setw(8) << *(pickup_cars[index]) << setw(8) << *(compact_cars[index]) << setw(11) << *(sedan_cars[index]) << endl
where the *(pickup_cars[index]) is set to " " and the seat value gives error = read memory from 0x6 failed (0 of 4 bytes read). That is also set to NULL.
Here is the code of the RegistrationSystem constructor:
RegistrationSystem::RegistrationSystem(void) {
file_name = "seat_credits.txt";
menu_response = 0;
ifstream inFile(file_name);
if(!inFile.is_open()) {
cout << "Error opening file. Terminating...";
exit(1);
}
// Read file to set passengers and their credits in rowers array
int count = 0;
while(!inFile.eof() && count < 24) {
string first, last;
int credits;
inFile >> first >> last >> credits;
string fullName = first + ' ' + last;
rowers[count] = new Passenger(fullName, credits);
count++;
}
// Assign all the cars to the arrays
pickup_cars[0] = new Pickup("PURPLE");
pickup_cars[1] = new Pickup("YELLOW");
pickup_cars[2] = new Pickup("RED");
compact_cars[0] = new Compact("GREEN");
compact_cars[1] = new Compact("BLUE");
compact_cars[2] = new Compact("YELLOW");
sedan_cars[0] = new Sedan("RED");
sedan_cars[1] = new Sedan("GREEN");
sedan_cars[2] = new Sedan("BLUE");
inFile.close();
}
The problem occurred when the input file stream was still open and I was creating new instances and assigning their addresses to pointers before I closed the file. After I switched the order and closed the file, then assigned pointers the addresses of the new objects the problem went away.
These operations were happening inside of the constructor of the RegistrationSystem class. Here is the new code:
RegistrationSystem::RegistrationSystem(void) {
file_name = "seat_credits.txt";
menu_response = 0;
ifstream inFile(file_name);
if(!inFile.is_open()) {
cout << "Error opening file. Terminating...";
exit(1);
}
// Read file to set passengers and their credits in rowers array
int count = 0;
while(!inFile.eof() && count < 24) {
string first, last;
int credits;
inFile >> first >> last >> credits;
string fullName = first + ' ' + last;
rowers[count] = new Passenger(fullName, credits);
count++;
}
inFile.close();
// Assign all the cars to the arrays
pickup_cars[0] = new Pickup("PURPLE");
pickup_cars[1] = new Pickup("YELLOW");
pickup_cars[2] = new Pickup("RED");
compact_cars[0] = new Compact("GREEN");
compact_cars[1] = new Compact("BLUE");
compact_cars[2] = new Compact("YELLOW");
sedan_cars[0] = new Sedan("RED");
sedan_cars[1] = new Sedan("GREEN");
sedan_cars[2] = new Sedan("BLUE");
}
The line inFile.close() was placed after all the array assignments. Moving it above them solved the problem of losing the first data member of my Pickup object.

Vector Isn't Creating Multiple Class Objects

I have a vector that stores multiple class objects for later access. This way my program can create new objects during runtime. This is done like so:
vector<Person> peopleVector;
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
This function should print out each objects "name" every time the code runs (it's a function that runs multiple times). However, when I run this, somehow the vector does not increase in size. If you add cout << peopleVector.size(); to that code, you will find that each time it runs, it gets one (obviously assuming you also have the class code which I have below).
I'm curious why I can't create multiple objects in the class.
Class.h
#pragma once
#include <iostream>
using namespace std;
class Person {
public:
Person(string personName, int personAge);
string name;
int age;
};
Person::Person(string personName, int personAge) {
name = personName;
age = personAge;
}
Main.cpp
#include "Class.h"
#include <random>
int main() {
// Necessary for random numbers
srand(time(0));
string name = names[rand() % 82]; // Array with a lot of names
int age = 4 + (rand() % 95);
}
// Create a new person
void newPerson(string name, int age) {
vector<Person> peopleVector;
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
}
Just FYI those #includes might be a little bit off because I took that code out of a large section that had like 15 includes.
You are creating an empty vector each time you call your newPerson() function, and then you add a single person to it.
You then display the contents of that vector. What else can it contain, other than the single person that you added?
Problem
Every time a function runs, all local variables inside the function are re-created in their default state. That means that every time you call newPerson, it just recreates peopleVector.
Solution
There are two solutions:
Have newPerson take a reference to a vector, and add it on to that
make peopleVector static, so that it isn't re-initialized every time
First solution:
// Create a new person; add it to peopleVector
// The function takes a reference to the vector you want to add it to
void newPerson(string name, int age, vector<Person>& peopleVector) {
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
}
Second solution: mark peopleVector as static
// create a new person; add it to peopleVector
void newPerson(string name, int age) {
// Marking peopleVector as static prevents it from being re-initialized
static vector<Person> peopleVector;
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
}

I keep receiving -2 as my updated salary

I am doing the following with my program:
1) Write the class definition for a class named Employee with name and salary as employee objects. The class contains two member functions: the constructor and a function that allows a program to assign values to the data members.
2) Add two member functions to the Employee class. One member function should allow any program using an employee object to view the contents of the salary data member. The other member function should allow the program to view the contents of the employee name data member.
3) Add another member function to the Employeeclass. The member function should calculate an employee objects new salary, based on a raise percentage provided by the program using the object. Before calculating the raise, the member function should verify that the raise percentage is greater than or equal to zero. If the raise percentage is less than zero, the member function should display an error message.
4) Write a main function that will create an array of employee objects, assign values to the objects, display the names and current salaries for all objects, ask user for the raise percentage and then calculate and display new salaries for all objects.
However, I receive -2 as my new salary after I input the data from the keyboard. I figured another set of eyes could see what I can't and would highly appreciate if someone can lend a hand, or at least steer me in the right direction. Perhaps it is a logic error, or something wrong with my declarations. Thank you for your time.
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
class EMPLOYEE
{
public:
EMPLOYEE();//
EMPLOYEE(string name, int salary);//
public:
string name;//name to be input
int salary;//salary to be input
int percentage_raise;
int updated_salary;
public:
int enter_values();
int output_values();
int NEW_SALARY();
};
//default constructor
EMPLOYEE::EMPLOYEE()
{
name = "";
salary = 0;
}
//constructor with name/salary variables
EMPLOYEE::EMPLOYEE(string NAME, int SALARY)
{
name= NAME;
salary= SALARY;
}
//name and salary to be input...
int EMPLOYEE::enter_values()
{ cout<<"Enter name and salary: ";
cin>> name;
cin>>salary;
return 0;
}
//output
int EMPLOYEE::output_values()
{ cout<<"Name: "<<name<<endl;
cout<<"Salary: "<<salary<<endl;
return 0;
}
//
int EMPLOYEE::NEW_SALARY()
{
if ( percentage_raise >= 0)
{ int updated_salary;
int raise= (salary *percentage_raise)/100;
updated_salary += raise;
}
else if(percentage_raise< 0)
{ cout<<"Error Message"<<endl;
}
return 0;
}
int main()
{
EMPLOYEE employees[100];
EMPLOYEE percent_to_be_raised;
int i;
for(i =0 ;i<100 ; i++)
{ employees[i]=EMPLOYEE();
employees[i].enter_values();
employees[i].name;
employees[i].salary;
// employees[i].NEW_SALARY();
employees[i].output_values();
cout<<"How much should the salary be raised by?"<<endl;
cin>>percent_to_be_raised.percentage_raise;
cout<<"-----------------------------"<<endl;
cout<<employees[i].name <<"'s new salary is "<<percent_to_be_raised.updated_salary<<endl;
}
}
You need to rewrite this quite alot.
A few pointers:
EMPLOYEE percent_to_be_raised;
Is completely off base. The task states that this calculation should be done in an employee member function. I.e. the raise should be performed as
Employee alfred;
std::cin>> alfred.salary;
double raise;
std::cin>> raise;
alfred.raise_salary(raise); // this is what the task asks for.
Use a naming convention.
Employee
is fine for a c++ class with a capitalized class name convention. EMPLOYEE is not; this looks like a macro name.
Member function usually starts with non-capitalized
Employee::new_salary( the_salary );
Follow the examples you have available from the course material.
Of course
employees[i].name;
employees[i].salary;
Does not do anything. Please review your code in detail and start at the first spot you don't understand.
Note that the OP coding style convention is used to assist the OP. I am aware of the proper naming convention for classes, member functions, and class data members (e.g. see the answer by Captain Giraffe for more).
Inside of:
int EMPLOYEE::NEW_SALARY()
{
if ( percentage_raise >= 0)
{ int updated_salary;
int raise= (salary *percentage_raise)/100;
updated_salary += raise;
}
} // added this to close the function properly
there is a locally declared variable, which is typed identically to the public access data member of the same name. What is the intention here?
Most likely it should be coded like so:
int EMPLOYEE::NEW_SALARY()
{
if ( percentage_raise >= 0)
{
int raise = (salary *percentage_raise)/100;
updated_salary += raise;
}
} // added this to close the function properly
There are design considerations for having all class member data public, as well as having an integer for a percentage. From the calculation above, it looks like only values of one, two, three, etc. are allowed for the percentage number. What is the class supposed to do if a raise is 3.75 percent?
The constructor has to set ALL class data members to something meaningful too. For example, the percentage_raise and updated_salary variables are ignored. Most likely the default constructor has to be updated to:
//default constructor
EMPLOYEE::EMPLOYEE()
{
name = "";
salary = 0;
percentage_raise = 0;
updated_salary = 0;
}
The name and salary constructor has to be updated too. It should probably look like (using the style convention posted by the OP):
//constructor with name/salary variables
EMPLOYEE::EMPLOYEE(string NAME, int SALARY)
{
name = NAME;
salary = SALARY;
percentage_raise = 0;
updated_salary = salary;
}

Declaring my member function parameters/arguments

class Seller
{
private:
float salestotal; // run total of sales in dollars
int lapTopSold; // running total of lap top computers sold
int deskTopSold; // running total of desk top computers sold
int tabletSold; // running total of tablet computers sold
string name; // name of the seller
Seller::Seller(string newname)
{
name = newname;
salestotal = 0.0;
lapTopSold = 0;
deskTopSold = 0;
tabletSold = 0;
}
bool Seller::SellerHasName ( string nameToSearch )
{
if(name == nameToSearch)
return true;
else
return false;
}
class SellerList
{
private:
int num; // current number of salespeople in the list
Seller salespeople[MAX_SELLERS];
public:
// default constructor to make an empty list
SellerList()
{
num = 0;
}
// member functions
// If a salesperson with thisname is in the SellerList, this
// function returns the associated index; otherwise, return NOT_FOUND.
// Params: in
int Find ( string thisName );
void Add(string sellerName);
void Output(string sellerName);
};
int SellerList::Find(string thisName)
{
for(int i = 0; i < MAX_SELLERS; i++)
if(salespeople[i].SellerHasName(thisName))
return i;
return NOT_FOUND;
}
// Add a salesperson to the salespeople list IF the list is not full
// and if the list doesn't already contain the same name.
void SellerList::Add(string sellerName)
{
Seller(sellerName);
num++;
}
I have some issues with the parameters in my functions in my SellerList class. I want to add someone to the salespeople array so I have a record of all my sellers... Bob, Pam, Tim, etc... My constructor Seller(sellerName) creates a Seller with name sellerName.
How do I add this Seller to the Salespeople array and have capability of a way to pull the data back out and use it in more functions such as a Update function, or an output function?
MAX_SELLERS = 10.... I guess my issue is not knowing whether to use parameters of only
Add(string) or Add(Seller, string). Any help would be appreciated.
Not reinvent the wheel. Choose the container appropiate to your problem. In this case, because you are referencing/searching Sellers by a std::string, I suggest you to use a hash table like std::unordered_map (Or std::map search tree if you don't have access to C++11):
int main()
{
std::unordered_map<Seller> sellers;
//Add example:
sellers["seller name string here"] = /* put a seller here */;
//Search example:
std::unordered_map<Seller>::iterator it_result = sellers.find( "seller name string here" );
if( it_result != std::end( sellers ) )
std::cout << "Seller found!" << std::endl;
else
std::cout << "Seller not found :(" << std::endl;
}
How about using STD vector inside of SellerList instead of the array.
vector<Seller> x;
you can do x.push_back(Seller(...)) or x[0].SellerHasName() and x.size() will give you the number of sellers.
maybe something like this?
// Add a salesperson to the salespeople list IF the list is not full
// and if the list doesn't already contain the same name.
void SellerList::Add(string sellerName)
{
if(num < MAX_SELLERS)
salespeople[num++] = new Seller(sellerName);
}