C++ Classes, Basic overloading errors - c++

I am trying to make a program that makes a class called student that as a student ID, an array of grades, and a number showing how many grades are in the array. The class is supposed to have member methods that enter a student ID number, enter a single test grade and update the total number of grades entered, and compute an average grade and display the student ID followed by the average grade. Here is my code so far.
#include <iostream>
using namespace std;
class Student
{
public:
int StudentID;
double Grades[5];
int NumberOfGrades;
// Member functions declared here
int setID(int id);
double setGrades(double g[5]);
double getAverage(void);
};
// make them functions work, son.
int Student::setID(int ID)
{
cout << "Please enter in the student's ID number: ";
cin >> ID;
return 0;
}
double Student::setGrades(double g[5])
{
for (int i = 0; i < 5; i++)
{
cout << "Please enter in grade number " << i ;
cin >> g[i];
NumberOfGrades++;
}
return 0;
}
double Student::getAverage(void)
{
int sum = 0,average; // declare what I need in average
for (int i = 0; i < 5; i++)
{
sum = sum + Grades[i];
}
average = sum / NumberOfGrades;
cout << "The average for " << StudentID << " is " << average;
return 0;
}
int main ()
{
Student Student1;
Student1.setID; // error
Student1.setGrades; // error
Student1.getAverage();
}
I am getting the error saying that it cannot resolve the address of overloaded function. Can someone explain to me what an overloaded fuction is, in simplest terms possible? Also, if possible, could anyone explain why I got that error in my code?

First of all, you need to actually call these functions:
Student1.setID -> Student1.setID()
Student1.setGrades -> Student1.setGrades()
That's not enough, though, these function require arguments (int and double[5], respectively). So:
int id = 65;
double grades[5] = { 3.5, 4.0, 4.0, 3.0, 4.5 };
Student1.setID(id);
Student1.setGrades(grades);
This will only remove compiler errors, though. Perhaps you don't see this, but your functions are implemented incorrectly:
int Student::setID(int ID)
{
cout << "Please enter in the student's ID number: ";
cin >> ID; //you fill ID, which is a temporary variable!
return 0;
}
Also, if you ask user inside setID() for id, what is the purpose of this parameter? Remove it - change setID(int ID) to setID():
int Student::setID()
{
int input_id;
cout << "Please enter in the student's ID number: ";
cin >> input_id;
this->StudentID = input_id;
return 0;
}

I see a few major problems with the code:
int Student::setID(int ID)
{
cout << "Please enter in the student's ID number: ";
//ID is local. Assigning any value to it will have no effect on the class
cin >> ID;
//You might as well not return anything if the function is purely impure
return 0;
}
The other issue is a "setter" shouldn't be taking input from a user, and doing an assignment; those are 2 separate tasks. I'd set up this function as:
void Student::setID(int ID)
{
StudentID = ID;
}
Notice that we're assigning to the StudentID a value passed in as an argument. Use like:
//In main
Student student;
int newStudentID = 1234;
student.setID(newStudentID);

Related

How to update the members of objects in the array constructed from another class?

I have 2 separate classes in C++,which are Algorithms class and Student class, each of have the following members and methods.
#include <iostream>
using namespace std;
#define MAX 10
class Student {
private:
int ID;
string name;
string surname;
int quiz_scores[4];
public:
Student()
{
ID = 0;
name = "" ;
surname = "";
quiz_scores[4] = {0};
}
void setID(int ID_set);
int getID();
void setName(string name_set);
string getName();
void setSurName(string surname_set);
string getSurName();
void setQuizScores(int* quizscores);
const int* getQuizScores() const;
};
and Algorithms class as follows:
class Algorithms{
private:
Student students[MAX];
int num =0 ; // The current number of students in the course, initially 0.
float weightQ;
float weightHW;
float weightF;
public:
Algorithms()
{
students[num] = {};
weightQ = 0.3;
weightHW = 0.3;
weightF = 0.4;
}
int getNum(); // Returns how many students are in the course
void addNewStudent(Student new_student);
And here is the methods declerations of Student class and Algorithms class respectively.
// Method declerations for the class Student
void Student :: setID(int ID_set){
ID = ID_set;
}
int Student :: getID(){
return ID;
}
void Student :: setName(string name_set){
name = name_set;
}
string Student :: getName(){
return name;
}
void Student :: setSurName(string surname_set){
surname = surname_set;
}
string Student :: getSurName(){
return surname;
}
void Student :: setQuizScores(int* quizscores){
for(int i = 0; i<4; i++){
quiz_scores[i] = quizscores[i];
}
}
const int* Student :: getQuizScores() const {
return quiz_scores; }
// Method declerations for the class Algorithms
int Algorithms:: getNum(){
return num;
}
void Algorithms :: addNewStudent(Student new_student){
students[num] = new_student ;
num = num + 1;
}
void Algorithms :: updateWeights(float weightQ_update, float weightHW_update, float weightF_update){
weightQ = weightQ_update;
weightHW = weightHW_update;
weightF = weightF_update;
}
void Algorithms :: getStudentInfo(int ID_given, Algorithms &algorithms){
for(int i = 0; i<MAX; i++){
if(ID_given == students[i].getID()){
cout << "Student Name & Surname : " << students[i].getName() << " " << students[i].getSurName()<<"\n";
cout << "Quiz results :" << students[i].getQuizScores();
}
}
}
I have also user-interface in the main. It calls the following functions
void addNewStudent(int ID, string name, string surname, Algorithms &algorithms){
Student student;
student.setID(ID);
student.setName(name);
student.setSurName(surname);
algorithms.addNewStudent(student);
}
void showStudent(int ID, Algorithms &algorithms){
algorithms.getStudentInfo(ID, algorithms);
}
Both work properly with the code in main as below
int main(){
Algorithms ECE101;
int x;
int ID;
string name, surname;
string option_1 = "1) Add a student ";
string option_2 = "2) Search a student by ID";
string option_3 = "3) Change a student’s score";
cout << "Welcome to the ECE101 Classroom Interface"<<"\n";
cout << "Choose your option\n";
cin >> x;
do {
if (x == 1) {
cout << "Enter the student ID ";
cin >> ID;
cout << endl;
cout << "Enter the student name ";
cin >> name;
cout << endl;
cout << "Enter the student surname " ;
cin >> surname;
addNewStudent(ID, name, surname, ECE101);
}
else if (x==2){
cout << "Enter the student ID\n";
cin >> ID;
showStudent(ID, ECE101);
}
else {
int quiz_grades[4];
cout << "Enter the student ID";
cin >> ID;
cout << endl;
cout << "Enter the quiz grades" << endl;
for (int i = 0 ; i<4 ; i++) {
cin >> quiz_grades[i];
}
changeStudentScores(ID, quiz_grades);
}
The problem here comes from changeStudentScores(ID, quiz_grades, ECE101)
What I want to do is the program should take the array of 4 numbers(corresponds to the quiz grades) and set to the student, whose ID's given by the user. (Of course, firstly the student should be added to the course by the option 1) BUT, I could not pass the array to the changeStudentScores , where it is implemented by
void changeStudentScores(int ID, int* quizscores ){
// Problem occurs here, creating new students object is not so logical, but I tried.
Student student;
student.setID(ID);
student.setQuizScores();
// I just try to pass the quiz grades writing by the user to the set method, which set quiz grades to the students.
After choose the option 2 which shows the information about the students given the ID, I see the correct name and surname, but I could not update the quiz grades.
RESTRICTIONS:
There should be no other method and data members other than the written methods and data members.
But we can implement additional methods and functions (but not class data
members)
getStudentInfo(int ID_given, Algorithms &algorithms) function must return student information given ID, but my implementation I could use with void
QUESTIONS:
How can I implement correctly the changeStudentScores function so that the user can update the existing student quiz score?
My getStudentInfo(int ID_given, Algorithms &algorithms) function returns nothing that I can use for getting information. So need to be returned the student information, so the return type must not be void.
What is the general idea behind updating the members of the objects, which are used in another class with some data structure(here is array.)

how can I print dynamic array in c++ I need explanation to this question

This is the question my teacher gave me:
Construct a structure Employee that consists of the following fields:
ID, name, degree, age
A function that creates an object (a variable of Employee type), fills it from the user the, then returns it.
A function that receives an object (a variable of Employee type) and prints its fields.
Inside the main function:
Ask the user to specify the number of employees.
Create a dynamic array of the size specified by the user for the employees.
Inside a loop, fill the array elements one at a time by calling the first function.
Inside another loop, print the array elements one at a time by calling the second function.
I tried to solve it although I didn't understand it and this is what I have, Pleas help:
struct Employee
{
int ID;
char name[10];
char degree;
int age;
};
int fillin()
{ Employee employee;
cout<<"Enter employee ID, NAME, DEGREE and AGE:\n";
cin>>employee.ID;
cin>>employee.name;
cin>>employee.degree;
cin>>employee.age;
}
int print()
{
Employee employee;
cout<<"ID: "<< employee.ID<<" , ";
cout<<"NAME: "<< employee.name<<" , ";
cout<<"Degree: "<< employee.degree<<" , ";
cout<<"AGE: "<< employee.age<<".\n ";
}
int main()
{
int num;
cout<<"Enter number of employees: ";
cin>> num;
string *name= new string[num];
for(int i = 0; i < num;i++)
{
name[i]=fillin();
}
for(int j : name){
print();
}
return 0;
}
A function can have parameters and return a value. So here, fillin should return an Employee object, and print should take an Employee (or better a const reference) parameter:
Employee fillin()
{ Employee employee;
cout<<"Enter employee ID, NAME, DEGREE and AGE:\n";
cin>>employee.ID;
cin>>employee.name;
cin>>employee.degree;
cin>>employee.age;
return employee; // return the local object
}
void print(const Employee& employee)
{
cout<<"ID: "<< employee.ID<<" , ";
cout<<"NAME: "<< employee.name<<" , ";
cout<<"Degree: "<< employee.degree<<" , ";
cout<<"AGE: "<< employee.age<<".\n ";
}
Your main function could become:
int main()
{
int num;
cout<<"Enter number of employees: ";
cin>> num;
Employee *name= new Employee[num];
for(int i = 0; i < num;i++)
{
name[i]=fillin();
}
for(int i=0; i<num; i++){
print(name[i]);
}
return 0;
}
Of course, you should check that the input methods return valid values (check cin after each read)
There are several issues with the code, below is the working example.
the functions should receive and return parameters somehow, references are used in the code
array should be of appropriate type
wrong iterator used
However, keep in mind that there are more issues with the code, like no boundary checking, it is better to use STL library... consider this just as a starting point.
#include <iostream>
using namespace std;
struct Employee
{
int ID;
char name[10];
char degree;
int age;
};
int fillin(Employee& employee)
{
cout<<"Enter employee ID, NAME, DEGREE and AGE:\n";
cin>>employee.ID;
cin>>employee.name;
cin>>employee.degree;
cin>>employee.age;
}
int print(const Employee& employee)
{
cout<<"ID: "<< employee.ID<<" , ";
cout<<"NAME: "<< employee.name<<" , ";
cout<<"Degree: "<< employee.degree<<" , ";
cout<<"AGE: "<< employee.age<<".\n ";
}
int main()
{
int num;
cout<<"Enter number of employees: ";
cin>> num;
Employee *emp= new Employee[num];
for(int i = 0; i < num;i++)
{
fillin(emp[i]);
}
for(int j = 0; j< num; j++){
print(emp[j]);
}
return 0;
}
Employee fillin()
{
Employee employee;
cout << "Enter employee ID, NAME, DEGREE and AGE:\n";
cin >> employee.ID;
cin >> employee.name;
cin >> employee.degree;
cin >> employee.age;
return employee;
}
void print(Employee emp)
{
cout << "ID: " << emp.ID << " , ";
cout << "NAME: " << emp.name << " , ";
cout << "Degree: " << emp.degree << " , ";
cout << "AGE: " << emp.age << ".\n ";
}
This should help put you on the right track. You just need the dynamic array to accept Employee objects and then you need to supply the objects to print when you call print(someEmployeeObject) in main.
Okay, I have a variety of comments on your code. First, do not use character arrays. Use string instead:
#include <string>
struct Employee
{
int ID;
std::string name;
char degree;
int age;
};
String allows for dynamic-length strings, so if someone enters a really, really long name, you won't overrun the space. It will just handle it. Plus there are a bunch of other advantages.
Next, let's change this method just slightly:
Employee fillin() {
Employee employee;
cout<<"Enter employee ID, NAME, DEGREE and AGE:\n";
cin>>employee.ID;
cin>>employee.name;
cin>>employee.degree;
cin>>employee.age;
return employee;
}
You weren't returning anything at all, but you need to return the employee you're creating. So this is a small change.
And now a small change to the print method:
#include <iostream>
std::ostream & operator<<(std::ostream &ostr, const Employee &employee) {
{
ostr <<"ID: "<< employee.ID<<" , ";
ostr <<"NAME: "<< employee.name<<" , ";
ostr <<"Degree: "<< employee.degree<<" , ";
ostr <<"AGE: "<< employee.age<<".\n ";
return ostr;
}
Then to use it:
std::cout << employee;
This is the C++ way to do it and lets you use the exact same method if you want to dump the employee somewhere else (like a file).
And finally, small changes to your main:
#include
int main()
{
std::vector employees;
int num;
cout<<"Enter number of employees: ";
cin>> num;
for(int i = 0; i < num;i++)
{
employees.push_back(fillin());
}
for (const Employee &employee: employees) {
std::cout << employee;
}
return 0;
}
Let's talk about this. First, rather than using a fixed-length array, we're using a vector. This is a dynamic-length array similar to how string is a dynamic length string. You can push_back() to append items to the array. When defining it, you specify what it holds. So in this case, I have a vector of Employee objects.
I started with your for-loop, but I call the new version of fillin to actually get an employee record, and then I push them into the vector.
Then there's a second for-loop. You may not be familiar with this style. Basically that's a for-loop that iterates over every element of employees -- the ones we just did push_back() on. And then I use the output method I wrote earlier.
You were close. You were just missing a few key things -- basically passing elements into your methods and returning elements.

c++ instantiate several classes if a condition is true

Is there a way I can make this work?
I want to create 5 instances of bank if age is greater than 17, but I am getting this error:
[Error] no matching function for call to 'Bank::Bank()'
I need to get this right for my assignment in school.
#include <iostream>
#include <string>
using namespace std;
class Bank{
string Fullname;
string StateOfOrigin;
int Age;
public:
Bank(string name, string state, int age){
Fullname = name;
StateOfOrigin = state;
Age = age;
}
string getname(){
return Fullname;
}
string getstate(){
return StateOfOrigin;
}
int getage(){
return Age;
}
};
int main(){
Bank customer[20];
int x,y,z,age;
string name;
string state;
cout<<"==============================="<<endl;
cout<<"Welcome To Hojma Bank.Plc"<<endl;
cout<<"How many accounts do you want to create? \n";
cin>>y;
for(int k = 0; k < y; k++){
cout<<"Please input your fullname"<<endl;
cin>>name;
cout<<"Please input your state of origin"<<endl;
cin>>state;
cout<<"Please input your age";cout<<endl;
cin>>age;
if(age >= 18){
Bank customer[y](name,state,age);
cout << customer[y].getname();
}
}
}
Bank customer[20];
Here you default-construct twenty Bank objects (oddly called customer??). Or, at least, you tried to, but your Bank class has no default constructor. Neither should it, from what I can tell.
Bank customer[y](name,state,age);
cout << customer[y].getname();
Here I guess you tried to "declare" individual array elements, but it doesn't work like that.
Also your usage of y is wrong; you can accept y maximum, but you probably meant to use the current loop counter value, k. That's broken too because you have a filter on age so you might skip some array elements.
Why not use a nice tasty std::vector, and add new customers at will? Then you can also get rid of those confusing ints, half of which you're not even using.
int main()
{
int y = 0;
cout << "===============================\n";
cout << "Welcome To Hojma Bank.Plc\n";
cout << "How many accounts do you want to create?" << endl;
cin >> y;
std::vector<Bank> customers;
for (int i = 0; i < y; i++) {
int age;
string name;
string state;
cout << "Please input your full name" << endl;
cin >> name;
cout << "Please input your state of origin" << endl;
cin >> state;
cout << "Please input your age" << endl;
cin >> age;
if (age >= 18){
customers.emplace_back(name,state,age);
cout << customer.back().getname();
}
}
}
You could do with some error checking on your user input, too. And rename that class to Customer.
If you create an array of objects (Bank customer[20]), the class needs to have a default constructor. Just define something like this:
Bank() : Fullname(""), StateOfOrigin(""), Age(0) {}

class pointer unitialized local variable

Recently in my c++ class we have learned about pointers and classes.
I'm trying to make a program that has a class Student, which we will point to give each student a name and test score.
After entering both name and test score, they are sorted and then listed in order of highest to lowest.
I believe all my syntax to be correct, however I am still learning. The problem I am having is that the first time I use my class I get an uninitialized local variable error, any help on how to fix this?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <array>
using namespace std;
class Student {
private:
double score;
string name;
public:
void setScore(double a) {
score = a;
}
double getScore() {
return score;
}
void setName(string b) {
name = b;
}
string getName() {
return name;
}
};
void sorting(Student*, int);
int main()
{
Student *students;
string name;
int score;
int *count;
count = new int;
cout << "How many students? ";
cin >> *count;
while (*count <= 0) {
cout << "ERROR: The number of students must be greater than 0.\n";
cin >> *count;
}
for (int i = 0; i < *count; i++) {
cout << "Please enter the students name: ";
cin >> name;
students[i].setName(name);
cout << "Please enter " << students[i].getName() << "'s score: ";
cin >> score;
while (score < 0) {
cout << "ERROR: Score must be a positive number.\n";
cin >> score;
}
students[i].setScore(score);
}
sorting(students, *count);
for (int i = 0; i < *count; i++) {
cout << students[i].getName() << ": " << students[i].getScore() << endl;
}
system("PAUSE");
return 0;
}
void sorting(Student *s, int size) {
for (int i = 0; i < size; i++) {
for (int j = i; j < size; j++) {
if (s[j].getScore() > s[(j + 1)].getScore()) {
int tmp = s[(j + 1)].getScore();
s[(j + 1)].setScore(s[j].getScore());
s[j].setScore(tmp);
string tmp1 = s[(j + 1)].getName();
s[(j + 1)].setName(s[j].getName());
s[j].setName(tmp1);
}
}
}
}
First off, your Student class can be simplified to this:
struct Student {
double score;
std::string name;
};
Because the accessors do absolutely nothing. I've also added the std:: prefix because using namespace std is considered a bad practice.
Now, instead of using the pointer to store the students, include vector and use that:
std::cout << "How many students? ";
int count;
std::cin >> count;
std::vector<Student> students(count);
The loading routine can also be simplified given the absence of accesors:
for (auto& student : students) {
std::cout << "Please enter the students name: ";
std::cin >> student.name;
std::cout << "Please enter " << student.name << "'s score: ";
std::cin >> student.score;
while (score < 0) {
std::cout << "ERROR: Score must be a positive number.\n";
std::cin >> student.score;
}
}
And actually once you have that, you could just put it in istream& operator>>(istream&, Student&) and reduce it to:
std::copy_n(std::istream_iterator<Student>(std::cin), students.size(), students.begin());
No need now for temporary variables anymore (and even if you want to use them, they should be defined just before the use, so inside of the loop).
The last thing is your sorting routine. First off, there's std::sort that you can use instead if you simply provide a comparator:
std::sort(
begin(students),
end(students),
[](Student const& a, Student const& b) { return b.score < a.score; }
);
If you insist on writing the sorting routine yourself, at least use std::swap.

My program for calculating the final grade doesn't calculate it and I can't tell why

I've been trying to write a C++ program that calculates your end of year grade (an exercise given by the Google for Education C++ course). The program works, except for the fact that it doesn't calculate your final grade, instead, it just outputs "0". I have searched the code and can't seem to find the problem.
#include <iostream>
using namespace std;
int check(int a) {
if (!(cin >> a)) {
cout << "Come on, that isn't a score" << endl;
return 0;
}
}
int assignments() {
int assignment1 = 0;
int assignment2 = 0;
int assignment3 = 0;
int assignment4 = 0;
cout << "Enter the score for the first assignment. ";
check(assignment1);
cout << "Enter the score for the second assignment. ";
check(assignment2);
cout << "Enter the score for the third assignment. ";
check(assignment3);
cout << "Enter the score for the fourth assignment. ";
check(assignment4);
return ((assignment1 + assignment2 + assignment3 + assignment4) / 4 * 0.4);
}
int mid() {
int midterm = 0;
cout << "Enter the score for the midterm. ";
check(midterm);
return (midterm * 0.15);
}
int finalex() {
int finals = 0;
cout << "Enter the score for the final. ";
check(finals);
return (finals * 0.35);
}
int participation() {
int parti = 0;
cout << "Enter the class participation grade. ";
check(parti);
return (parti * 0.1);
}
int main() {
int assign = assignments();
int midt = mid();
int fingra = finalex();
int partigra = participation();
cout << "The final grade is: " << assign + midt + fingra + partigra << endl;
}
(The reason I have a different program for every grade type is because the course states that you should make as many functions as possible)
Either you should pass value to check() as reference or make check to return input value.
Change
int check(int a)
to
int check(int& a)
Second method
Modify check to
int check(int a) {
if (!(cin >> a)) {
cout << "Come on, that isn't a score" << endl;
return a;
}
}
And use return value to assign input to variables. Like
int midterm = 0;
cout << "Enter the score for the midterm. ";
midterm=check(midterm);
Your cin >> a statements updates value of a local variable which is gone as soon as check() returns. You want to update value of variables that are actually used for calculating grades. Just change the function check() to pass by reference check(int &a) or pass a pointer check(int *a)