-3

I am trying to solve how to get the average of 2-4 objects ideally with the method beeing inside my class.

class Student {

public:
    string name;
    int grades;

public:
    void val(string name, int grades) 
    {
        this->name = name;
        this->grades = grades;
    }
};

int main() {
    Student p1,p2,p3,p4;
    p1.val("john", 10);
    p2.val("dean", 5);
    p3.val("george", 11);
    p4.val("fred", 19);
    cout << p1.name << " " << p1.grades << endl;
    cout << p2.name << " " << p2.grades << endl;
    cout << p3.name << " " << p3.grades << endl;
    cout << p4.name << " " << p4.grades << endl;
    return 0;
}

i just cant figure out a way to get for example the average of p1.grades/p2.grades/p3.grades/p4.grades ideally i want the method in the class and if possible the answer as simple as possible (nothing too advanced to understand).

genpfault
  • 51,148
  • 11
  • 85
  • 139
John
  • 1
  • *nothing too advanced to understand* -- It is highly subjective on what is "advanced". What is advanced to you may be simple to another beginner. Answers (if any) will be posted at whatever level the answerer desires. Remember that others are searching for answers on StackOverflow, and may come across the title you will give this thread. – PaulMcKenzie Apr 12 '22 at 14:37
  • you have 4 different student objects. Using a member function of `Student` to calculate their average grade is neither the most simple nor does it make much sense, because each `Student` has only access to its own `grade` – 463035818_is_not_an_ai Apr 12 '22 at 14:38
  • you should learn about container, specifically `std::vector` and algorithms, specifically `std::accumulate`. However, don't expect it to be simple, C++ is not a simple language – 463035818_is_not_an_ai Apr 12 '22 at 14:39
  • ah sorry for that , what would you recomend of doing in order to solve this , my end goal is to find the average of their scores, if this method i choose is not good what should i study / reasearch in order to improve – John Apr 12 '22 at 14:40
  • @John You should learn about containers, or even simple arrays. What if there were 50 students? Would you create 50 separate variables? That would be nuts, wouldn't you agree? – PaulMcKenzie Apr 12 '22 at 14:41
  • do you know how to calcuate the average without using a function? Do that first. Then you can try to write a function that takes 4 `Student`s as parameter. Next you can try to use an array or vector – 463035818_is_not_an_ai Apr 12 '22 at 14:41
  • i do yeah , also have looked and practiced vectors , but my biggest problem right now with vectors is that i cant figure out how to pushback the value of an object into the vector, specially with methods beeing inside the class, for example how to make an int vector and then get the int part of my objects and pushback it in the vector then finding the average would be easier – John Apr 12 '22 at 14:43
  • @John First, your `Student` class fails to initialize `grades`, and no, `val` does not count. What will be printed if this happens: `Student s; std::cout << s.grade;`? The output could be any integer. – PaulMcKenzie Apr 12 '22 at 14:47
  • @C++ is a _large_ language with _complex_parts. That does not mean you cannot use it to write _simple_ code - you do not need to use all the tools in the bag after all. That said, clearly a `std::vector` or even an array of objects would be more appropriate and flexible than discrete `Student` objects. – Clifford Apr 12 '22 at 17:28

2 Answers2

1

You can use just a for loop as for example

int sum = 0;
for ( const Student *student : { &p1, &p2, &p3, &p4 } )
{
    sum += student->grades;
}

int average = sum / 4;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • thank you very much this is what i was looking for , is there a way to impliment this inside my class and call it in my main ?(if so how could i have done this), sorry for the questions , this just feel a bit rough on my current knowledge – John Apr 12 '22 at 14:56
  • 1
    @John It can be done, but I'm afraid you won't understand the solution unless you know about class constructors, vectors, pointers and `static` class members already. And it would be a rather bad example, it doesn't make sense for a `Student` to know about all other students from typical point of view. – Yksisarvinen Apr 12 '22 at 15:04
  • ah i see , i will go study and research some more then , thank you very very much guys for your effort and time have a great day – John Apr 12 '22 at 15:07
0

There are many "clever" ways you could express this in C++, but there are come fundamentals of programming in general and OOP specifically that you should incorporate into this exercise before getting in to more advanced C++.

First of all, if you have more than one of an object to be processed together as a collection then you should use a container or array that may be iterated. The simplest container in C++ is an array - they are built-in to the language rather than part of the library. There are all sorts of reasons why in practice you might not use an array, but for this exercise perhaps the simplicity makes it appropriate - one thing at a time.

So instead of four discrete objects p1, p2 etc. you might have Student p[4] ;.

Your class design could be improved. For example in OOP, it is generally bad form to expose data members as public. Hiding the data and controlling access via member functions is preferred. Moreover since your class has no constructor, it is possible to instantiate an "empty" Student with no name or grade. That might be useful, but you should at least have an initialiser constructor so that the objects can be instantiated and initialised in the same expression. That would for example allow your student array to be instantiated and initialised thus:

   // An initialised array of students
   Student students[] = { Student("john", 10),
                          Student("dean", 5),
                          Student("george", 11),
                          Student("fred", 19) } ;

The number of elements in students in this case is fixed and determined by the number of initialisers and has value sizeof(students) / sizeof(*students). This is one reason you might in practice prefer a more flexible container such as a std::vector, but that is perhaps another question.

So the Student class might then look like:

class Student 
{
    public:
        // Constructor with initialiser list
        Student(std::string name, int grades) : m_name(name),
                                                m_grades(grades)
        {}

        // Read-only member accessors
        std::string name(){ return m_name ; }
        int grades(){ return m_grades ; }

    private :
        std::string m_name;
        int m_grades;

};

Now given that the array can be iterated by indexing zero to sizeof(students) / sizeof(*students) - 1, you can output the data and accumulate the grade sum as follows:

int student_count = sizeof(students) / sizeof(*students) ;
double grade_sum = 0 ;

for( size_t i = 0; i < student_count; i++ )
{
    int grade = students[i].grades() ;
    std::cout << students[i].name() << " " << students[i].grades() << std::endl ;
    grade_sum += grade ;
    
}

And then report the grade average thus:

std::cout << "Grade avg. = " << grade_sum / student_count << std::endl ;

Pulling all that together:

#include <string>
#include <iostream>

class Student 
{
    public:
        Student(std::string name, int grades) : m_name(name),
                                                m_grades(grades)
        {}

        std::string name(){ return m_name ; }
        int grades(){ return m_grades ; }

    private :
        std::string m_name;
        int m_grades;

};

int main() 
{
    Student students[] = { Student("john", 10),
                           Student("dean", 5),
                           Student("george", 11),
                           Student("fred", 19) } ;

    int student_count = sizeof(students) / sizeof(*students) ;
    double grade_sum = 0 ;
    
    for( size_t i = 0; i < student_count; i++ )
    {
        int grade = students[i].grades() ;
        std::cout << students[i].name() << " " << students[i].grades() << std::endl ;
        grade_sum += grade ;
        
    }
    
    std::cout << "Grade avg. = " << grade_sum / student_count << std::endl ;

    return 0;
}

With respect to:

"ideally i want the method in the class"

That does not really make much sense. The class represents a single student, whilst the average pertains to the collection of Student objects. However - if you really must then, you could make the grade sum and student count static members and accumulate the count and sum as students are instantited via the constructor thus:

class Student 
{
    public:
        Student(std::string name, int grades) : m_name(name),
                                                m_grades(grades)
        {
            m_grade_sum += grades ;
            m_student_count++ ;
        }

        std::string name(){ return m_name ; }
        int grades(){ return m_grades ; }
        
        static double averageGrade() 
        { 
            return static_cast<double>(m_grade_sum) / m_student_count ;
        }
        
        static int Count(){ return m_student_count; }

    private :
        std::string m_name;
        int m_grades;
        static int m_grade_sum ;
        static int m_student_count ;

};

int Student::m_grade_sum = 0 ;
int Student::m_student_count = 0 ;

Then the main() becomes:

int main() 
{
    Student students[] = { Student("john", 10),
                           Student("dean", 5),
                           Student("george", 11),
                           Student("fred", 19) } ;

    for( size_t i = 0; i < Student::Count(); i++ )
    {
        int grade = students[i].grades() ;
        std::cout << students[i].name() << " " << students[i].grades() << std::endl ;
    }
    
    std::cout << "Grade avg. = " << Student::averageGrade() << std::endl ;

    return 0;
}

It gets complicated and error prone perhaps when you might need to remove and/or amend Students after instantiation.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • Thank you incredible much for your effort and time taken to reply this , i did origanally thought to make it with an array or a vector , and then get the average on main ,although it also dint make a lot of sense in my head and i did a lot of effort and attempts i got close some times but it ,my instructions was to try and do it inside the class, wich kinda overwhelmed thinking its imposible on my current knowledge, and overall making it pretty undesirble and made me want to stop, try thinking the solution. I will try to do it again with the help from your generous instructions and help. – John Apr 23 '22 at 05:30