Figure 7.14 shows the output that summarizes the 10 grades we store in an object of the next version of class GradeBook
(Figs. 7.15–7.16), which uses an array
of integers to store the grades of 10 students for a single exam. This eliminates the need to repeatedly input the same set of grades. array grades
is declared as a data member in line 28 of Fig. 7.15—therefore, each GradeBook
object maintains its own set of grades.
Welcome to the grade book for
CS101 Introduction to C++ Programming!
The grades are:
Student 1: 87
Student 2: 68
Student 3: 94
Student 4: 100
Student 5: 83
Student 6: 78
Student 7: 85
Student 8: 91
Student 9: 76
Student 10: 87
Class average is 84.90
Lowest grade is 68
Highest grade is 100
Grade distribution:
0-9:
10-19:
20-29:
30-39:
40-49:
50-59:
60-69: *
70-79: **
80-89: ****
90-99: **
100: *
1 // Fig. 7.15: GradeBook.h
2 // Definition of class GradeBook that uses an array to store test grades.
3 // Member functions are defined in GradeBook.cpp
4 #include <string>
5 #include <array>
6
7 // GradeBook class definition
8 class GradeBook
9 {
10 public:
11 // constant -- number of students who took the test
12 static const size_t students = 10; // note public data
13
14 // constructor initializes course name and array of grades
15 GradeBook( const std::string &, const std::array< int, students > & );
16
17 void setCourseName( const std::string & ); // set the course name
18 string getCourseName() const; // retrieve the course name
19 void displayMessage() const; // display a welcome message
20 void processGrades() const; // perform operations on the grade data
21 int getMinimum() const; // find the minimum grade for the test
22 int getMaximum() const; // find the maximum grade for the test
23 double getAverage() const; // determine the average grade for the test
24 void outputBarChart() const; // output bar chart of grade distribution
25 void outputGrades() const; // output the contents of the grades array
26 private:
27 std::string courseName; // course name for this grade book
28 std::array< int, students > grades; // array of student grades
29 }; // end class GradeBook
1 // Fig. 7.16: GradeBook.cpp
2 // GradeBook class member functions manipulating
3 // an array of grades.
4 #include <iostream>
5 #include <iomanip>
6 #include "GradeBook.h" // GradeBook class definition
7 using namespace std;
8
9 // constructor initializes courseName and grades array
10 GradeBook::GradeBook( const string &name,
11 const array< int, students > &gradesArray )
12 : courseName( name ), grades( gradesArray )
13 {
14 } // end GradeBook constructor
15
16 // function to set the course name
17 void GradeBook::setCourseName( const string &name )
18 {
19 courseName = name; // store the course name
20 } // end function setCourseName
21
22 // function to retrieve the course name
23 string GradeBook::getCourseName() const
24 {
25 return courseName;
26 } // end function getCourseName
27
28 // display a welcome message to the GradeBook user
29 void GradeBook::displayMessage() const
30 {
31 // this statement calls getCourseName to get the
32 // name of the course this GradeBook represents
33 cout << "Welcome to the grade book for
" << getCourseName() << "!"
34 << endl;
35 } // end function displayMessage
36
37 // perform various operations on the data
38 void GradeBook::processGrades() const
39 {
40 // output grades array
41 outputGrades();
42
43 // call function getAverage to calculate the average grade
44 cout << setprecision( 2 ) << fixed;
45 cout << "
Class average is " << getAverage() << endl;
46
47 // call functions getMinimum and getMaximum
48 cout << "Lowest grade is " << getMinimum() << "
Highest grade is "
49 << getMaximum() << endl;
50
51 // call function outputBarChart to print grade distribution chart
52 outputBarChart();
53 } // end function processGrades
54
55 // find minimum grade
56 int GradeBook::getMinimum() const
57 {
58 int lowGrade = 100; // assume lowest grade is 100
59
60 // loop through grades array
61 for ( int grade : grades )
62 {
63 // if current grade lower than lowGrade, assign it to lowGrade
64 if ( grade < lowGrade )
65 lowGrade = grade; // new lowest grade
66 } // end for
67
68 return lowGrade; // return lowest grade
69 } // end function getMinimum
70
71 // find maximum grade
72 int GradeBook::getMaximum() const
73 {
74 int highGrade = 0; // assume highest grade is 0
75
76 // loop through grades array
77 for ( int grade : grades )
78 {
79 // if current grade higher than highGrade, assign it to highGrade
80 if ( grade > highGrade )
81 highGrade = grade; // new highest grade
82 } // end for
83
84 return highGrade; // return highest grade
85 } // end function getMaximum
86
87 // determine average grade for test
88 double GradeBook::getAverage() const
89 {
90 int total = 0; // initialize total
91
92 // sum grades in array
93 for ( int grade : grades )
94 total += grade;
95
96 // return average of grades
97 return static_cast< double >( total ) / grades.size();
98 } // end function getAverage
99
100 // output bar chart displaying grade distribution
101 void GradeBook::outputBarChart() const
102 {
103 cout << "
Grade distribution:" << endl;
104
105 // stores frequency of grades in each range of 10 grades
106 const size_t frequencySize = 11;
107 array< unsigned int, frequencySize > frequency = {}; // init to 0s
108
109 // for each grade, increment the appropriate frequency
110 for ( int grade : grades )
111 ++frequency[ grade / 10 ];
112
113 // for each grade frequency, print bar in chart
114 for ( size_t count = 0; count < frequencySize; ++count )
115 {
116 // output bar labels ("0-9:", ..., "90-99:", "100:" )
117 if ( 0 == count )
118 cout << " 0-9: ";
119 else if ( 10 == count )
120 cout << " 100: ";
121 else
122 cout << count * 10 << "-" << ( count * 10 ) + 9 << ": ";
123
124 // print bar of asterisks
125 for ( unsigned int stars = 0; stars < frequency[ count ]; ++stars )
126 cout << '*';
127
128 cout << endl; // start a new line of output
129 } // end outer for
130 } // end function outputBarChart
131
132 // output the contents of the grades array
133 void GradeBook::outputGrades() const
134 {
135 cout << "
The grades are:
";
136
137 // output each student's grade
138 for ( size_t student = 0; student < grades.size(); ++student )
139 cout << "Student " << setw( 2 ) << student + 1 << ": " << setw( 3 )
140 << grades[ student ] << endl;
141 } // end function outputGrades
The size of the array
in line 28 of Fig. 7.15 is specified by public static const
data member students
(declared in line 12), which is public
so that it’s accessible to the class’s clients. We’ll soon see an example of a client program using this constant. Declaring students
with the const
qualifier indicates that this data member is constant—its value cannot be changed after being initialized.
Keyword static
in this variable declaration indicates that the data member is shared by all objects of the class—so in this particular implementation of class GradeBook
, all GradeBook
objects store grades for the same number of students. Recall from Section 3.4 that when each object of a class maintains its own copy of an attribute, the variable that represents the attribute is known as a data member—each object (instance) of the class has a separate copy of the variable in memory. There are variables for which each object of a class does not have a separate copy. That is the case with static data members, which are also known as class variables. When objects of a class containing static
data members are created, all the objects share one copy of the class’s static
data members. A static
data member can be accessed within the class definition and the member-function definitions like any other data member. As you’ll soon see, a public static
data member can also be accessed outside of the class, even when no objects of the class exist, using the class name followed by the scope resolution operator (::
) and the name of the data member. You’ll learn more about static
data members in Chapter 9.