I have read several of the previously asked questions on this topic, but can't seem to find the answer I'm looking for. When I run the program I receive no errors, but I get a lot of garbage data. I know it's because I'm not passing the parameters right, but I'm new to c++ and specifically how to use pointers correctly. To make it simple: I am passing an employee object through PrintCheck(), which calls the CalcSalary() function, which must use GetHours() and GetWage() to access member data to do calculations and return the correct salary. Would appreciate any explanations as to why I am generating garbage data!
I have a class:
class Employee
{
private:
int employeeNumber;
string name;
string streetAddress;
string phoneNumber;
double hourlyWage;
double hoursWorkedperWeek;
public:
Employee(void);
Employee(int, string, string, string, double, double);
int GetEmployeeNum() const;
void SetEmployeeNum(int);
string GetName() const;
void SetName(string);
string GetAddress() const;
void SetAddress(string);
string GetPhone() const;
void SetPhone(string);
double GetWage() const;
void SetWage(double);
double GetHours() const;
void SetHours(double);
double CalcPay(double, double);
};
I also have a function that needs to interact with the class:
void PrintCheck(Employee&);
My main function looks like:
void main()
{
Employee joe(1, "Joe Blo", "125 Cool St.", "555 555 5555", 10.00, 45); //create employee 1
Employee jane(2, "Jane Doe", "521 Dumb St.", "1 800 555 5555", 12.50, 30); //create employee 2
PrintCheck(joe); //print check
}
The printcheck function looks like:
void PrintCheck(Employee& a)
{
cout << "Pay to the order of " << a.GetName() << "...................................";
cout << a.CalcPay(a.GetWage(), a.GetHours()) << endl;
cout << "Hours worked: " << a.GetHours() << endl;
cout << "Hourly wage: " << a.GetWage() << endl;
}
Calcpay function is:
double Employee::CalcPay(double h, double w)
{
double salary = 0;
int OT = 40;
double timeandahalf = 1.5;
double STATE = .075;
double FED = .20;
if (h > OT) // overtime
{
salary = h * (w * timeandahalf); // calc time and a half
salary = salary * STATE; // calc state deductions
salary = salary * FED; // calc federal deductions
}
else
{
salary = h * w; // calc salary
salary = salary * STATE; // calc state deductions
salary = salary * FED; // calc federal deductions
}
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(PRECISION);
return salary;
}
My "get" functions all follow this pattern:
int Employee::GetEmployeeNum() const
{
return employeeNumber;
}
My expected output would be:
Pay to the order of: Joe Blo............ $salary.
Hours worked: $hours.
Hourly wage: $wage.
What I got:
Pay to the order of: ........................ 128509280503000000000000000000000000000.00 (this number is long, but I didn't feel like typing them all)
Hours worked: -9723636237 (same, just tons of bs numbers)
Hourly wage: (the exact same number as above)
My class constructor:
Employee::Employee(int en, string n, string a, string p, double w, double h)
{
int employeeNumber = en;
string name = n;
string streetAddress = a;
string phoneNumber = p;
double hourlyWage = w;
double hoursWorkedperWeek = h;
}
Employee::Employee()
{
}
Your Employee::Employee(int en, string n, string a, string p, double w, double h) is declaring new local variables inside it and therefore shadowing the member variables inside your class. So in reality, you never properly initialized any of its members during construction.
The following should correct that problem:
Employee::Employee(int en, string n, string a, string p, double w, double h)
: employeeNumber ( en ),
name ( n ),
streetAddress ( a ),
phoneNumber ( p ),
hourlyWage ( w ),
hoursWorkedperWeek ( h )
{
}
This is the error
Employee::Employee(int en, string n, string a, string p, double w, double h)
{
int employeeNumber = en;
string name = n;
string streetAddress = a;
string phoneNumber = p;
double hourlyWage = w;
double hoursWorkedperWeek = h;
}
it should be
Employee::Employee(int en, string n, string a, string p, double w, double h)
{
employeeNumber = en;
name = n;
streetAddress = a;
phoneNumber = p;
hourlyWage = w;
hoursWorkedperWeek = h;
}
or even better it should be as in greatwolf's answer.
The error in your version is that you've declared variables in your constructor with exactly the same names as the members of your class. These variables hide your class members, so your constructor does not initialise your class. So you get garbage.
Related
I've been looking around to see if anyone has a similar issue to me and i couldn't find anything. I am prompting the user to type in the name of the planet they wish to delete. My function will locate the position of the planet within the vector objects.
The purpose of this function is to delete a object based on the position i pass through the function parameters.
Planet Class
class Planet {
private:
string name;
double diameter;
double mass;
public:
const double G = 6.67408e-11;
void setName(string n);
bool setDiameter(double d);
bool setMass(double m);
string getName();
double getDiameter();
double getMass();
double CalcSa();
double CalcV();
double CalcDensity();
double CalcG();
string InputS(string x);
double InputD(string x);
Planet();
};
double ReadDouble(double input) {
//Verifys that that user entered in a correct number
while (cin.fail() != 0) {
cerr << "Enter a valid number: ";
cin.clear();
cin.ignore(255, '\n');
cin >> input;
}
return input;
}
string Planet::InputS(string x) {
string user_input;
cout << x;
cin >> user_input;
return user_input;
}
double Planet::InputD(string x) {
double user_input;
cout << x;
cin >> user_input;
user_input = ReadDouble(user_input);
return user_input;
}
Planet::Planet() {
name;
diameter = 0.0;
mass = 0.0;
}
void Planet::setName(string n) {
name = n;
}
bool Planet::setDiameter(double d) {
bool rv = false;
if (d > 0.0) {
rv = true;
diameter = d;
}
return rv;
}
bool Planet::setMass(double m) {
bool rv = false;
if (m > 0.0) {
rv = true;
mass = m;
}
return rv;
}
string Planet::getName() {
return name;
}
double Planet::getMass() {
return mass;
}
double Planet::getDiameter() {
return diameter;
}
double Planet::CalcSa() {
double sa = 4.0 * M_PI * pow((diameter / 2.0), 2.0);
return sa;
}
double Planet::CalcV() {
double v = (4.0 / 3.0) * M_PI * pow((diameter / 2.0), 3.0);
return v;
}
double Planet::CalcDensity() {
double den = mass / CalcV();
return den;
}
double Planet::CalcG() {
double r = diameter / 2.0;
double grav = (G * mass) / (pow(r, 2.0));
return grav;
}
My issue is with this line of code:
l.erase(l.begin() + n);
void DeleteVector(vector<Planet>& l, int n) {
if (int len = l.size() > 0) {
cout << l[n].getName() << " was removed from the list.\n";
l.erase(l.begin() + n);
}
}
i pass in the vector of planets which is a class. and then i pass in the position "n" which i wish to remove from the vector of objects.
I get the following error:
Error C2280 'Planet &Planet::operator =(const Planet &)': attempting to reference a deleted function
Any help or guidance would be appreciated.
The copy assignment operator for your class Planet is implicitly deleted by your compiler, because it has a const member.
See Deleted implicitly-declared copy assignment operator:
A defaulted copy assignment operator for class T is defined as deleted if any of the following is true:
T has a non-static data member of non-class type (or array thereof) that is const;
You probably meant G to be static const:
static const double G;
and then outside of your class:
const double Planet::G = 6.67408e-11;
I'm trying to create a class for employees, and have a problem with its constructor.
My class looks like that (please note the name parameter which is char* type):
class Employee {
int id;
char * name ;
float salary;
int hours;
int extra;
public:
//constructor
Employee(int, char *, float, int, int);
//Getters and Setters:
void setId(int a) { id = a; }
int getId() { return id; }
void setName(char * c) { name = c; }
char * getName() { return name; }
void setSalary(float f) { salary = f; }
float getSalary() { return salary; }
void setHours(int h) { hours = h; }
int getHours() { return hours; }
void setExtra(int e) { extra = e; }
int getExtra() { return extra; }
};
I built a constructor and I want it to have default parameters, and I don't know how to deal with the name parameter to have a default of let's say "unknown".
This is the constructor:
Employee::Employee(int i = 123456789, char * na, float sal = 30, int ho = 45, int ex = 10)
{
id = i;
name = na;
salary = sal;
hours = ho;
extra = ex;
}
You can use a character array, and initialise the array to point to the first element of the array. You can store the array for example as a static member:
// in the class definition
inline static char default_name[] = "unknown";
// in argument list of the constructor
... char * na = default_name, ...
Although, you may want to consider whether it makes sense for name to be pointer to non-const. Perhaps a pointer to const would suffice. In such case, you could initialise it to point to the literal "unknown" directly.
A cleaner version
class Employee {
int id = 0;
char *name = nullptr;
float salary = 0.0;
int hours = 0;
int extra = 0;
And you don't need to have constructors, this depends on the case, but you get the idea that by initializing the variables on the definition you reduce the inconsistency of having multiples constructors for example
hi reached a point where im not sure how to proceed.
the main objective of my program:
1) read 5 values from a file(.csv)
date (class with 3 variables - day,month, year)
time (class with 2 variables - minute, hour)
float wSpeed (under class weather)
float temperature (under class weather)
float solarRadiation (under class weather)
2) put into an object
3) put it into a vector
main
int main()
{
string filename;
ifstream input;
Vector<weather> windlog; //have a vector called windlog
cout <<"enter file name:" <<endl;
cin >> filename;
input.open(filename.c_str());
input.ignore(500,'\n');
string sDay, sMonth, sYear, sHH, sMM, wind, solar, temperature;
date d1;
time t1;
weather w1;
getline(input, sDay,'/'); //stop getting input at '/'
getline(input, sMonth,'/');
getline(input, sYear,' ');
getline(input, sHH,':');
getline(input, sMM,',');
int day1 = atoi(sDay.c_str()); //convert string to int (atoi)
int month1 = atoi(sMonth.c_str());
int year1 = atoi(sYear.c_str());
int hour1 = atoi(sHH.c_str());
int min1 = atoi(sMM.c_str());
d1.setDate(day1,month1,year1); //set date using converted string
t1.setTime(min1, hour1); //set time using converted string
// skip the first 9 columns of .csv file
for(int i=0; i<9; i++)
{
input.ignore(50, ','); //ignore ','
}
//location now at wSpeed date of .csv file
getline(input, wind,',');
float wS1 = atof(wind.c_str()); // convert string to float
//next location is the location solarRadiation
getline(input, solar,',');
float sR1= atof(solar.c_str()); // convert string to float
//move 5 columns
for(int i=0; i< 5; i++)
{
input.ignore(50, ',');
}
//at location of temperature
getline(input, temperature,'\n');
float temperature1 = atof(temperature.c_str()); // convert string to
float
//when i print it out, it gives me the correct data
/*
cout << d1; //date class that contains dd,mm,yy
cout << t1;//time class that contains hh, mm
cout << wS1 ;
cout << sR1;
cout << temperature1 << endl;
*/
//trying to put these data into an object file: weather
//i tried doing something like this
weather obj1(wS1, sR1, temperature1, d1, t1);
cout << objt1;//gives me weird values but when i cout each variable, it
works out fine
not going to write the whole date/time.h/cpp cause i think it'll take up too much space
date.h
public:
setday, setmonth, setyear, setdate(day,month,year);
getday,getmonth,getyear;
private: day,month,year;
time.h
public:
setminute, sethour, settime(minute,hour);
getminute,get hour;
private: minute, hour;
weather class(where im having the problems)
.H
#ifndef H_WEATHER
#define H_WEATHER
#include <iostream>
#include <string>
#include "time.h"
#include "date.h"
using namespace std;
class weather: public date, time
{
friend ostream& operator << (ostream&, const weather&);
friend istream& operator >> (istream&, weather&);
public:
weather();
weather(float wSpeed, float solarRadiation, float temperature,
date d1, time t1);
~weather();
void setWspeed(float wSpeed);
void setSolarRadiation(float solarRadiation);
void setTemperature(float temperature);
float getWspeed() const ;
float getSolarRadiation() const;
float getTemperature() const;
void setWeather(float wS, float sR, float t,date d1, time t1);
date getDate();
time getTime();
date d1;//mm, hh
time t1;//dd,mm,yy
private:
float wSpeed;
float solarRadiation;
float temperature;
};
#endif
.CPP
#include <iostream>
#include "weather.h"
#include "date.h"
#include "time.h"
weather::weather()
{
wSpeed=0;
solarRadiation=0;
temperature = 0;
}
weather::weather(float wS, float sR, float t, date d1, time
t1):date(day,month,year), time(hours,minute)
{
wS = wS;
sR = sR;
t =t;
d1.setDate(day,month, year);
t1.setTime(hours,minute);
}
weather::~weather() {}
void weather::setWeather(float wS, float sR, float t)
{
wSpeed =wS;
solarRadiation=sR;
temperature =t;
}
void weather::setWspeed(float wS)
{
wSpeed =wS;
}
void weather::setSolarRadiation(float sR)
{
solarRadiation=sR;
}
void weather::setTemperature(float t)
{
temperature = t;
}
void weather::setWeather(float wS,float sR, float t, date d1, time
t1)
{
wSpeed=wS;
solarRadiation=sR;
temperature = t;
}
float weather::getWspeed() const
{
return wSpeed;
}
float weather::getSolarRadiation() const
{
return solarRadiation;
}
float weather::getTemperature() const
{
return temperature;
}
ostream& operator<< (ostream& osObject, const weather& weather1)
{
osObject << weather1.wSpeed <<" " << weather1.solarRadiation <<""
<< weather1.temperature << weather1.d1 << weather1.t1 ;
return osObject;
}
istream& operator >> (istream& isObject, weather& weather1)
{
isObject >> weather1.wSpeed>> weather1.solarRadiation >>
weather1.temperature >> weather1.d1 >> weather1.t1;
return isObject;
}
how do i put the values into an object? is it correct i have to use inheritance so i can overload the weather constructor so it can take a date and time class?
You almost have it, but...
You do NOT have to inherit to be able to work with a member object. In
class weather: public date, time
: public date, time is not necessary. It also implies the weather is a date and a time which makes no sense. Avoid inheriting unless there is some logical is-a relationship.
weather::weather(float wS, float sR, float t, date d1, time t1):
date(day,month,year), // you want the member name now, not the type
// plus where did day month and year come from?
time(hours,minute) // not ditto, but close enough.
{
wS = wS; // self assigns. In other word, does nothing
sR = sR; // ditto
t =t; // ditto
d1.setDate(day,month, year); // where did day month and year come from?
t1.setTime(hours,minute); // not ditto, but close enough.
}
Doesn't really do anything. It mostly has the parameters assigning to themselves. This is pointless because they are the same variable and they are temporary variables. What you want to do is assign to the member variables. This is a constructor, so you might as well use the Member Initializer List all the way through
weather::weather(float wS,
float sR,
float t,
date d1,
time t1) :
wSpeed(wS),
solarRadiation(sR),
temperature(t),
d1(d1), // note this is about the only time you can use the same name twice.
// Enjoy it. But don't do it. It confuses people.
t1(t1) // ditto
{
}
Then we get down to setWeather
void weather::setWeather(float wS, float sR, float t)
{
wSpeed =wS;
solarRadiation=sR;
temperature =t;
}
Does not match the definition in the class
void setWeather(float wS, float sR, float t,date d1, time t1);
So obviously we want something more like
void weather::setWeather(float wS, float sR, float t, date pd1, time pt1)
{
wSpeed = wS;
solarRadiation = sR;
temperature = t;
d1 = pd1;
t1 = pt1;
}
Note I did not repeat d1 in the parameter list. I changed it so I wouldn't have d1 = d1; which does nothing useful. It would be better to give both the member and the parameter more descriptive names. d1 conveys zero information about that the variable is and how it should be used.
I need to write the name, act# balance and address of the object that is stored in the vector, to a file.
I believe I have the program to push the objects into the vectors, but since they are vectors of object pointers I am having problems figure out how to call the object and print all 3 objects out.
Main.cpp
vector<Account*> accounts;
accounts.push_back(new Savings(new Person("Bilbo Baggins", "43 Bag End"), 1, 500, 0.075));
accounts.push_back(new Checking(new Person("Wizard Gandalf", "Crystal Palace"), 2, 1000.00, 2.00));
accounts.push_back(new Savings(new Person("Elf Elrond", "Rivendell"), 3, 1200, 0.050));
ofstream outFile;
outFile.open("accounts.txt");
if (outFile.fail())
{
cout << "\nYour file did not open, the program will now close!\n";
system("PAUSE");
return 0;
}
else
{
cout << "\nBINGO!!! It worked.\n\n";
system("PAUSE");
cout << "\n";
}
// New : Using a loop, send messages to each of the three Account objects to write themselves out to the file.
cout << "\nNow we are going to write the information to \"Accounts.txt\" \n\n";
system("PAUSE");
for (int i = 0; i < accounts.size(); i++) {
accounts[i]->writeAccount(outFile);
}
Account.h
#pragma once
#include <string>
#include <iostream>
#include "Person.h"
using namespace std;
// Account class - abstract/parent class
class Account
{
private:
int actNumber;
double actBallance;
Person PersonName;
public:
Account();
Account(int, double, Person*);
int getActNumber();
virtual double getActBallance();
string getName();
string getAdd();
void deposit(double);
void withdrawl(double);
virtual void writeAccount(ofstream&);
virtual void readAccount(ifstream&);
void testAccount(int i);
};
// Checking class: inherits from the Account class
class Checking : public Account
{
private:
double monthlyFee;
public:
Checking();
Checking(Person*, int, double, double);
void setMonthlyFee(double);
double getActBallance();
void writeAccount(ofstream&);
void readAccount(ifstream&);
};
// Savings class: inherits from the Account class
class Savings : public Account
{
private:
int interestRate;
public:
Savings();
Savings(Person*, int, double, double); // person, act#, Ballance, Interest Rate
void setInterestRate(double);
double getActBallance();
void writeAccount(ofstream&);
void readAccount(ifstream&);
};
Account.cpp
#include "Account.h"
#include <string>
using namespace std;
Account::Account()
{
actNumber = 0;
actBallance = 0.0;
}
Account::Account(int act, double bal, Person* name)
{
actNumber = act;
actBallance = bal;
}
int Account::getActNumber()
{
return actNumber;
}
double Account::getActBallance()
{
return actBallance;
}
string Account::getName()
{
return PersonName.getName();
}
string Account::getAdd()
{
return PersonName.getAddress();
}
void Account::deposit(double money)
{
actBallance += money;
}
void Account::withdrawl(double money)
{
actBallance -= money;
}
void Account::writeAccount(ofstream& output)
{
output << actNumber << "\n" << actBallance << "\n" << PersonName.getName() << "\n" << PersonName.getAddress() << endl;
}
void Account::readAccount(ifstream& output)
{
output >> actNumber;
output >> actBallance;
}
// Checking Account
Checking::Checking() {
monthlyFee = 0;
}
Checking::Checking(Person* per, int actNum, double bal, double interest) {
bal -= monthlyFee;
Account:Account(actNum, bal, per);
}
void Checking::setMonthlyFee(double fee) {
monthlyFee = fee;
}
double Checking::getActBallance() {
double ballance = Account::getActBallance();
return ballance = monthlyFee;
}
void Checking::readAccount(ifstream& output) {
int actNumber = Account::getActNumber();
int actBallance = Account::getActBallance() - monthlyFee;
output >> actNumber;
output >> actBallance;
}
void Checking::writeAccount(ofstream& output) {
int actNumber = Account::getActNumber();
int actBallance = Account::getActBallance();
output << actNumber << "\n" << actBallance << endl;
}
// Savings Account
Savings::Savings() {
interestRate = 0;
}
// Savings(Person, int, double, double) // person, act#, Ballance, Interest Rate
Savings::Savings(Person* per, int actNum, double bal, double interest) {
bal += (bal * interest);
Account:Account(actNum, bal, per);
}
void Savings::setInterestRate(double rate) {
interestRate = rate;
}
double Savings::getActBallance() {
double ballance = Account::getActBallance();
return ballance + (ballance * interestRate);
}
void Savings::readAccount(ifstream& output) {
double actBallance = Account::getActBallance();
int actNumber = Account::getActNumber();
actBallance += (actBallance * interestRate);
output >> actNumber;
output >> actBallance;
}
void Savings::writeAccount(ofstream& output) {
int actNumber = Account::getActNumber();
int actBallance = Account::getActBallance();
output << actNumber << "\n" << actBallance << endl;
}
I realize I am so far off... but I have been at this for HOURS and I can not figure out for the life of me, but to take the vector of object pointers and output the objects values.
Person.h
#pragma once
#include <string>
#include <fstream>
using namespace std;
class Person
{
private:
string name;
string address;
public:
Person();
Person(string a, string b);
string getName();
string getAddress();
void writePerson(ofstream&);
void readPerson(ifstream&);
};
Person.cpp
#include "Person.h"
#include <string>
using namespace std;
Person::Person()
{
name = "NAME";
address = "123 STREET";
}
Person::Person(string a, string b)
{
name = a;
address = b;
}
string Person::getName()
{
return name;
}
string Person::getAddress()
{
return address;
}
void Person::writePerson(ofstream& output)
{
output << name << " " << address << endl;
}
void Person::readPerson(ifstream& output)
{
output >> name;
output >> address;
Person(name, address);
}
Read again your course books on constructors: there are severe issues in all of your constructors. As a result, you don't initialize the object member variables, and you effectively end up printing lots of zeros and empty strings...
Firstly, for your base-class, you must initialize the person name. You should have written:
Account::Account(int act, double bal, Person* name)
: actNumber(act)
, actBallance(bal)
, PersonName(name)
{}
Secondly, for your derived classes, the initialisation of the base-class must be done in the initializer-list, not in the body of the ctor. Here is for exemple the correct definition for the Checking's ctor:
Checking::Checking(Person* per, int actNum, double bal, double interest)
: Account(actNum, bal, per)
, monthlyFee(-bal)
{}
Thirdly, be careful to initialize the member variables with the arguments of the ctor. You sometimes do the opposite and assign the ctor arguments with the (uninitialized) member variables.
BTW, Account is a base-class for a polymorphic hierarchy: thus, the Account destructor must be declared virtual.
I have an array of objects which all derive from the class BaseStudent.
BaseStudent**studentlist = new BaseStudent*[atoi(listSize.c_str())];
That array is populated with either derived Math, English or History objects. I'm now trying to print out specific data from each object in the array and output it to a file.
for (int j=0; j<atoi(listSize.c_str()); j++){
if(studentlist[j]->getMT() == ENGLISH){
output << studentlist[j]->GetFN()<<" "<<studentlist[j]->GetLN();
output << right << setw(42) << studentlist[j]->GetFinal(); // this is an English public function but I can't call this.
}
}
I need to be able to access the derived classes private member data from the array of objects.
Here's my header. As you can see I have a setter and getter for every protected member data.
#include <iostream>
#include <string>
using namespace std;
#ifndef BASESTUDENT_H
#define BASESTUDENT_H
enum MajorType {ENGLISH, HISTORY, MATH};
// *********************************************************************
// Base class. All other classes (Enlish, History, Math) inherit from
// this class.
// *********************************************************************
class BaseStudent
{
public:
BaseStudent();
BaseStudent(string fn, string ln, string m);
string GetFN(){return firstName;}
string GetLN(){return lastName;}
MajorType getMT(){return course;}
void SetFN(string fn){firstName = fn;}
void SetLN(string ln){lastName = ln;}
void SetMT(string m);
protected:
string firstName;
string lastName;
MajorType course;
}; // End Base class
// *********************************************************************
// Enlish class.
// *********************************************************************
class English: public BaseStudent
{
public:
English(string fn, string ln, string m, double a, double p, double mt, double f);
double FinalAverage();
double GetAttendance(){return attendance;}
double GetProject(){return project;}
double GetMidterm(){return midterm;}
double GetFinal(){return final;}
double GetFinalAverage(){return finalAverage;}
void SetAttendance(double a){attendance = a;}
void SetProject(double p){project = p;}
void SetMidterm(double m){midterm = m;}
void SetFinal(double f){final = f;}
void SetFinalAverage(double fa){finalAverage = fa;}
protected:
double attendance;
double project;
double midterm;
double final;
double finalAverage;
}; // End English class
// *********************************************************************
// History class.
// *********************************************************************
class History: public BaseStudent
{
public:
History(string fn, string ln, string m, double t, double mt, double f);
double FinalAverage();
double GetTermPaper(){return termPaper;}
double GetMidterm(){return midterm;}
double GetFinalExam(){return finalExam;}
double GetFinalAverage(){return finalAverage;}
double FinalExam(){return finalExam;}
void SetTermPaper(double t){termPaper = t;}
void SetMidterm(double m){midterm = m;}
void SetFinalExam(double f){finalExam = f;}
void SetFinalAverage(double fa){finalAverage = fa;}
protected:
double termPaper;
double midterm;
double finalExam;
double finalAverage;
}; // End History class.
// *********************************************************************
// Math class.
// *********************************************************************
class Math: public BaseStudent
{
public:
Math(string fn, string ln, string m, double q1, double q2, double q3,
double q4, double q, double t1, double t2, double f);
double FinalAverage();
double GetQuiz1(){return quiz1;}
double GetQuiz2(){return quiz2;}
double GetQuiz3(){return quiz3;}
double GetQuiz4(){return quiz4;}
double GetQuiz5(){return quiz5;}
double GetFinalExam(){return finalExam;}
double GetTest1(){return test1;}
double GetTest2(){return test2;}
double GetQuizAverage(){return quizAverage;}
double GetFinalAverage(){return finalAverage;}
void SetQuiz1(double q){quiz1 = q;}
void SetQuiz2(double q){quiz2 = q;}
void SetQuiz3(double q){quiz3 = q;}
void SetQuiz4(double q){quiz4 = q;}
void SetQuiz5(double q){quiz5 = q;}
void SetTest1(double q){test1 = q;}
void SetTest2(double q){test2 = q;}
void SetFinalExam(double q){finalExam = q;}
void SetQuizAverage();
void SetFinalAverage(double fa){finalAverage = fa;}
protected:
double quiz1;
double quiz2;
double quiz3;
double quiz4;
double quiz5;
double test1;
double test2;
double finalExam;
double quizAverage;
double finalAverage;
}; // End Math class.
#endif
Do I need some sort of implementation of virtual functions?
Here's my driver so far:
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip>
#include"basestudent.h"
using namespace std;
int main(void)
{
string listSize;
string fileIn = "";
string fileOut = "";
string firstname ="";
string lastname ="";
string major = "";
string eolDummy;
int mQuiz1, mQuiz2, mQuiz3, mQuiz4, mQuiz5, mTest1, mTest2, mFinalExam;
int eAttendance, eProject, eMidterm, eFinalExam;
int hTermPaper, hMidterm, hFinalExam;
ifstream input;
ofstream output;
do{
input.clear();
cout << "Please enter the filename: ";
cin >> fileIn;
cout << "Please enter an output name: ";
cin >> fileOut;
input.open(fileIn);
if (!input)
cout << "Invalid file, please enter again." << endl;
} while(!input);
input >> listSize;
BaseStudent**studentlist = new BaseStudent*[atoi(listSize.c_str())];
int i = 0;
while (!input.eof())
{
getline(input, lastname, ',');
getline(input, firstname, '\n');
input >> major;
if (major == "Math") {
input >>mQuiz1>>mQuiz2>>mQuiz3>>mQuiz4>>mQuiz5>>mTest1>>mTest2
>>mFinalExam>>eolDummy;
// Math Constructor call
// Array += object
studentlist[i] = new Math(firstname,lastname,major,mQuiz1,mQuiz2,mQuiz3,mQuiz4,mQuiz5,
mTest1,mTest2,mFinalExam);
}
else if (major == "History"){
input >>hTermPaper>>hMidterm>>hFinalExam>>eolDummy;
// History Constructor call
// Array += object
studentlist[i] = new History(firstname,lastname,major,hTermPaper,hMidterm,hFinalExam);
}
else if(major == "English"){
input >>eAttendance>>eProject>>eMidterm>>eFinalExam>>eolDummy;
// English Constructor call
// Array += object
studentlist[i] = new English(firstname,lastname,major,eAttendance,eProject,eMidterm,eFinalExam);
}
i++;
}
output.open(fileOut);
output << "Student Grade Summary" << endl;
output << "---------------------" << endl << endl;
output << "ENGLISH CLASS "<<endl<<endl;
output << "Student Final Final Letter"<<endl;
output << "Name Exam Avg Grade"<<endl;
output << "----------------------------------------------------------------"<<endl;
for (int j=0; j<atoi(listSize.c_str()); j++){
if(studentlist[j]->getMT() == ENGLISH){
output << studentlist[j]->GetFN()<<" "<<studentlist[j]->GetLN();
output << right << setw(42) << studentlist[j]->
input.close();
output.close();
return 0;
}
When you take the pointer from your array, you need to cast it using dynamic_cast to the appropriate class
e.g.
BaseStudent *p = somearray[0];
if ( English* pEnglish = dynamic_cast<English*>(p) )
{
// call the methods
cout << p->FinalAverage();
...
}
else if ( History* pHistory = dynamic_cast<History*>(p) )
{
// call the methods
}
else if ( Math* pMath = dynamic_cast<Math*>(p) )
{
// call the methods
}
btw use a vector instead of a raw array, it is more convenient and safer.
std::vector<BaseStudent*> yourvector;