cpp- static member and function - c++

I have the following student class with two similar function-
One is static and one is not.
class Student
{
public:
Student(std::string name_ , int const id_);
virtual ~Student();
void addGrade(int const grade2add);//grade above 100
void removeGrade (int const grade2remove); //update maxGrade
void print(); //id, name, grades
int getStudentMaxGrade();
static int getMaxGrade();
private:
std::string name; //max 20 chars
int const id; //5 digits, only digits
std::vector<int> grades;
float avg;
static int maxGrade;
};
The static int maxGradeis initialize with 0.
I implement the function:
int Student::maxGrade = 0;
int Student::getStudentMaxGrade()
{
return *max_element(grades.begin(), grades.end());
}
I'm not sure how to implement the static function.
I tried:
int Student::getMaxGrade()
{
maxGrade= *max_element(grades.begin(), grades.end());
return maxGrade;
}
But it doesn't work (doesn't compile)

The way you have your data laid out, each student knows nothing about the grades of the other students, and the class knows nothing about the grades of any particular student. This is good encapsulation, but in order to retrieve the maximum grade of all students, you have to include a bit of logic to keep track of the maximum grade that has been input. Something like this:
void Student::addGrade (int const grade) {
// do the stuff, add the grade
if (grade > maxGrade) // Check if the grade is higher than the previous
maxGrade = grade; // highest recorded grade and, if so, overwrite it.
}
This way, every time a higher grade is input, it becomes the new highest grade, and in that way the class always knows the highest grade without having to keep track of each and every student's grades.

Related

Nested structure function in c++

I'm having trouble with one of my assignments (or maybe I'm overthinking it?)
I need to create
a function to take integer parameters for number of students and tests.
Allocate the memory needed for the array of students and the array of test scores for each student.
Return a pointer to the array of Student structures. No display output is done in this function.
int main()
{
int studentNum;
int testNum;
cout << "How many students are there?\n";
cin >> studentNum;
cout << "How many tests are there?";
cin >> testNum;
system("pause");
return 0;
}
my function
GradeBook *initArrays(int s, int t)
{
GradeBook *ptr;
// Allocate the array of Student structures.
ptr = new GradeBook[s];
// Allocate an array of ints (to hold test scores)
// for each element of the array of Student structures.
for (int count = 0; count < s; count++)
{
ptr[count].tests = new int[t];
}
// Return a pointer to the array of structures.
return ptr;
}
edit: I have edited my function, could i get some opinions on that?
if you are writing this in c++, use classes. if i understand correctly, you should create a structure to save a students id,name,or something and a corresponding grade?
something like:
class Test{
public:
int id;
int grade;
Test(int id, int grade){
this->id = id;
this->grade = grade;
}
};
class Student{
public:
int id;
std::string name;
std::vector<Test> tests;
Student(int id, std::string name)
{
this->id = id;
this->name = name;
}
};
int main(){
vector<Student> students;
int studentnum;
for (int i = 0; i < studentnum; i++){
students.push_back(Student(i, "name"));
//insert all tests of the student by calling students[i].tests.push_back(Test(id, grade))
}
}
this way you don't have to allocate memory, which you can easily overlook freeing.
edit:
this is very basic and not a sophisticated solution, as the properties of the classes are all public.
edit 2:
typedef struct Test{
int id;
int grade;
}Test;
typedef struct Student{
int id;
std::string name;
Test * tests;
}Student;
int main(){
Student * students;
int studentnum;
students = (Student*)malloc(sizeof(Student)*studentnum);
for (int i = 0; i < studentnum; i++){
students[i]->id = id;
students[i]->name = "name";
student[i]->tests = (Test*)malloc(sizeof(Test)*numberofgradesofthatstudent);
for (int j = 0; j < numberofgradesofthatstudent; j++)
{
students[i]->tests[j]->id = testid;
students[i]->tests[j]->grade = grade;
}
}
}
this is schematic! new and malloc reserve memory on the heap, do not forget to free everything when you are done with it.
As said a little above, be careful using brackets {} to delimit your blocks.
Secondly,the syntax:
array[studIndex].Tests
supposes that the value array[studIndex] (here an integer) has a member value named Tests. But in this case it doesn't.
Think about your problem: you need to store two values "connected" to one another in a static array. The way I see it, you should try on with two dimensional arrays:
int 2dArray[nbStudents][nbTests];
If you don't want to bother with 2dimensional arrays, you can also try
int 2dArray[nbStudents * nbTests];
But for conveniance, it is often better to use 2d arrays.
Also, think about declaring your array before the for loops in your function.
Then concatenate two for loops as you did and I'll let you think about the rest...

Getting wrong output. Garbage value

Problem is, on execution, the value of roundCost I'm getting is
something like -1220673834. I post the entire program because I'm not
sure where I'm going wrong.
Note: I was asked to take all variables as double type and later,
roundCost should be of type int. So I used type conversion there.
#include<iostream>
using namespace std;
class Restaurant{
private:
double tip, tax,totalCost,mealCost, tipPercent, taxPercent;
int roundCost;
public:
int tipCalc(double)
{
tip=mealCost*(tipPercent/100);
return tip;
}
int taxCalc(double)
{
tax=mealCost*(taxPercent/100);
return tax;
}
int totalCost1()
{
totalCost=mealCost+tip+tax;
return totalCost;
}
int roundCost1(double)
{
roundCost=(int)totalCost;
return roundCost;
}
}; // class ends
int main()
{
double mealCost, tipPercent, taxPercent, totalCost;
int roundCost;
Restaurant ob1;
cout<<"\n Enter mealCost \n";
cin>>mealCost;
cout<<"\n Enter mealtipPercent \n";
cin>>tipPercent;
cout<<"\n Enter mealtaxPercent \n";
cin>>taxPercent;
ob1.tipCalc(tipPercent);
ob1.taxCalc(taxPercent);
ob1.totalCost1();
ob1.roundCost1(totalCost);
cout<<"\n Round of cost is "<<roundCost<<endl;
return 0;
}
One thing you seem to be missing is that variables in your class have a different scope then variables in your main. You set the mealcost in your main from cin but you never passed this variable to the class. I changed this to be done using a constructor that sets the meal cost on creation. In every class you make you should always add a constructor. Also, you should be naming the variables your passing to functions and then using the same name in the function. For example in the tax percent function i pass double t, t is the percent, we then use t in the calculation. Your round cost variable was also private so you needed to output it via a function.
Also int functions will return a value, if you are using this type of function you should be assigning the return variable to something, but since you are just setting things in your class you can use void functions for most. The only time you use a value in the main is in the roundcost so this one is good to have it return a value. As it is int (which i assumed you wanted) it will get no decimal points and it will simply cut off any decimals in the total cost (ie 75.75 would become 75).
#include<iostream>
using namespace std;
class Restaurant{
private:
double tip, tax,totalCost,mealCost;
int roundCost;
public:
Restaurant (double m)
{
mealCost = m;
}
void tipCalc(double t)
{
tip=mealCost*(t/100.0);
}
void taxCalc(double t)
{
tax=mealCost*(t/100.0);
}
void totalCost1()
{
totalCost=mealCost+tip+tax;
}
int roundCost1()
{
roundCost=(int)totalCost;
return roundCost;
}
}; // class ends
int main()
{
double mealCost, tipPercent, taxPercent, totalCost;
int roundCost;
cout<<"\n Enter mealCost \n";
cin>>mealCost;
Restaurant ob1(mealCost);
cout<<"\n Enter mealtipPercent \n";
cin>>tipPercent;
cout<<"\n Enter mealtaxPercent \n";
cin>>taxPercent;
ob1.tipCalc(tipPercent);
ob1.taxCalc(taxPercent);
ob1.totalCost1();
cout<<"\n Round of cost is "<<ob1.roundCost1()<<endl;
return 0;
}
Try to do a bit more research next time by using a debugger, outputting cout statements regularly and searching for the errors you find but this will give you a working code this time.

Getting average from passed subjects in structure

I enter info about the student first name lastname index number and degree for each subject.If the degree is over 5 the subject is passed and i get average from passed subjects.If i print the function like printf("%f",P.averagefunc()) the number is ok but i when i try to get the average to variable like float average=P.averagefunc(); inside struct student or float average=averagefunc(); inside struct subject and i print the result i get some weird number like -888266.00000.Any help how i can get the float function to float variable?
Please dont downvote the question i am new to this and i tried to explain my problem as best as i could.
struct subject{
int programming;
int electronics;
int calculus1;
int english;
int usersoftware;
float averagefunc()
{
int sum=0;
int passed=0;
if(programming>5)
{
sum+=programming;
passed++;
}
if(electronics>5)
{
sum+=electronics;
passed++;
}
if(calculus1>5)
{
sum+=calculus1;
passed++;
}
if(english>5)
{
sum+=english;
passed++;
}
if(usersoftware>5)
{
sum+=usersoftware;
passed++;
}
return (float)suma/(float)polozeni;
}
};
struct student{
char firstname[10];
char lastname[15];
int indexnumber;
struct subject P;
};

How do you make a vector of class objects?

I'm a bit confused as to how vectors work. What I'm trying to do is create a vector of 5 TaxBill objects. Then, what I want to do is read from an input file that has the names and different tax rates for 5 states. I want to store the name of the state in the object and the tax rates of the state in an array in int main().
Here's the input file called "Tax Rates.dat". The numbers are the sales, property and income tax rate, respectively, for each state.
TEXAS .0825 .02 -.03
MARYLAND .065 .04 .05
OHIO .03 .025 .03
CALIFORNIA .095 .055 .045
MAINE .02 .015 .02
Here's my class interface called "Tax Bill.h".
using namespace std;
class TaxBill
{
public:
void setValue(string, int);
void dataValid(double&, double&, double&);
private:
string Name;
int index;
double taxBill;
}
Here's my class implementation called "Tax Bill.cpp".
#include "Tax Bill.h"
void TaxBill::setValue(string name, int x)
{}
void TaxBill::dataValid(double& a, double& b, double& c)
{
if(a < 0)
a = 0;
if(b < 0)
b = 0;
if(c < 0)
c = 0;
return;
}
Here's my main source code so far.
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <vector>
#include "Tax Bill.h"
using namespace std;
int main()
{
const int SALARY = 100000,
HOUSE = 246000,
PURCHASE = 36000;
ifstream fin;
fin.open("Tax Rates.dat");
vector <TaxBill> someVector (5);
double sales,
property,
income;
double taxRates[5][3];
string name;
if(!fin)
return 0;
else
{
for(int i = 0; fin >> name >> sales >> property >> income; i++)
{
dataValid(sales, property, income);
taxRates[i][0] = sales;
taxRates[i][1] = property;
taxRates[i][2] = income;
}
}
The for loop is where I want to store the name of the state read from the input file and i into the string Name and index of the class object. The reason for the index is because later in the program I want to sort the objects in the vector alphabetically but not the array where the corresponding tax rates are stored.
I also don't want to use the function push_back().
I guess my question is, how do I make an vector of 5 class objects and access them?
Please keep in mind that my program is hardly complete and it's this one hurdle that's holding me back.
Here example of using vector from your code. Here you declare
vector <TaxBill> someVector (5);
So now, you have someVector[0] - [4] (5 in total). To use it, actually you just have to assign it like an normal array.
someVector[0].{insert property here}
But wait, in your class, there is no clear way to set the string Name and Index. So i think you forget to place it here, hence i make my own in the class.
class TaxBill
{
public:
void setValue(string Name, int Index){
name = Name; index = Index;
}
void dataValid(double&, double&, double&);
private:
string name;
int index;
double taxBill;
}
Now to use the vector, i just used the property this way
someVector[0].setValue("someName",1);
Tada, you get it to works. Btw, i dont know why you declare a procedure in the class, but you want to used it multiple times in main program. I mean this one
dataValid(sales, property, income);
to used it, i suggest you make a procedure in main program rather than in class and anyway that line should produce an error anyway. :)

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;
}