Need some clarification on Scoping in the Private Section of a Class
Aug 26, 2013 at 7:43pm UTC
I'm going through Paul Deitel's C++ fundamentals video course, and encountered a small scoping issue. Below is my GradeBook Class code. I left out the main cpp, as all it really does is initialize a grades array with 10 numbers, and calls the processGrades function in the class below.
I usually like to put my private variables section of a class first, so I can see them easily, but when I did that, I got a lot of scoping errors (i.e. "Grade not declared in scopre," "Numbers not declared in scope," etc.). Took me a while to figure out that placing private under public got rid of those scoping issues, and I just want to know why, so I can understand what I did wrong.
Thanks.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
#ifndef GRADEBOOK_H
#define GRADEBOOK_H
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class GradeBook{
public :
const static int students = 10;
GradeBook( string name, const int gradesArray[]){
setCourseName( name );
for ( int grade = 0; grade < students; grade++ )
grades[ grade ] = gradesArray[ grade ];
}
void setCourseName(string name){
courseName = name;
}
void processGrades(){
outputGrades();
cout << "\nClass average is " << setprecision(2) << fixed << getAverage() << endl;
cout << "Lowest grade is " << getMinimum() << "\nHighest grade is " << getMaximum() << endl << endl;
outputBarChart();
}
int getMinimum(){
int lowGrade = 100;
for (int grade = 0; grade < students; grade++){
if (grades[grade] < lowGrade)
lowGrade = grades[grade];
}
return lowGrade;
}
int getMaximum(){
int highGrade = 0;
for ( int grade = 0; grade < students; grade++){
if (grades[grade] > highGrade)
highGrade = grades[grade];
}
return highGrade;
}
void outputGrades(){
cout << "\nThe grades are:\n\n" ;
for (int student = 0; student < students; student++)
cout << "Student " << setw(2) << student + 1 << ": " << setw(3) << grades[student] << endl;
}
void outputBarChart(){
const int frequencySize = 11;
int frequency[frequencySize] = {};
for (int grade = 0; grade < students; grade++)
frequency[grades[grade]/10]++;
for (int count = 0; count < frequencySize; count++)
{
if (count == 0)
cout << "0-9: " ;
else if (count == 10)
cout << "100: " ;
else
cout << count * 10 << "-" << (count * 10) + 9 << ": " ;
for (int stars = 0; stars < frequency[count]; stars++)
cout << '*' ;
cout << endl;;
}}
double getAverage(){
int total = 0;
for (int grade = 0; grade < students; grade++)
total += grades[grade];
return static_cast <double >(total)/students;
}
string getCourseName(){
return courseName;
}
void displayMessage(){
cout << "\nWelcome to the GradeBook for " << getCourseName() << "!" << endl;
}
private :
int grades[students];
string courseName = "" ;
};
#endif // GRADEBOOK_H
Last edited on Aug 26, 2013 at 7:47pm UTC
Aug 26, 2013 at 7:50pm UTC
I think the issue is that your indentation style makes it incredibly difficult to tell what's inside the class vs what's inside a function.
The order and number of public/private/protected indicators does not matter.
I used NetBeans to automatically reformat your code, this is how NetBeans arranged it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
#ifndef GRADEBOOK_H
#define GRADEBOOK_H
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class GradeBook
{
public :
const static int students = 10;
GradeBook(string name, const int gradesArray[])
{
setCourseName(name);
for (int grade = 0; grade < students; grade++)
grades[ grade ] = gradesArray[ grade ];
}
void setCourseName(string name)
{
courseName = name;
}
void processGrades()
{
outputGrades();
cout << "\nClass average is " << setprecision(2) << fixed << getAverage() << endl;
cout << "Lowest grade is " << getMinimum() << "\nHighest grade is " << getMaximum() << endl << endl;
outputBarChart();
}
int getMinimum()
{
int lowGrade = 100;
for (int grade = 0; grade < students; grade++)
{
if (grades[grade] < lowGrade)
lowGrade = grades[grade];
}
return lowGrade;
}
int getMaximum()
{
int highGrade = 0;
for (int grade = 0; grade < students; grade++)
{
if (grades[grade] > highGrade)
highGrade = grades[grade];
}
return highGrade;
}
void outputGrades()
{
cout << "\nThe grades are:\n\n" ;
for (int student = 0; student < students; student++)
cout << "Student " << setw(2) << student + 1 << ": " << setw(3) << grades[student] << endl;
}
void outputBarChart()
{
const int frequencySize = 11;
int frequency[frequencySize] = {};
for (int grade = 0; grade < students; grade++)
frequency[grades[grade] / 10]++;
for (int count = 0; count < frequencySize; count++)
{
if (count == 0)
cout << "0-9: " ;
else if (count == 10)
cout << "100: " ;
else
cout << count * 10 << "-" << (count * 10) + 9 << ": " ;
for (int stars = 0; stars < frequency[count]; stars++)
cout << '*' ;
cout << endl;
;
}
}
double getAverage()
{
int total = 0;
for (int grade = 0; grade < students; grade++)
total += grades[grade];
return static_cast <double >(total) / students;
}
string getCourseName()
{
return courseName;
}
void displayMessage()
{
cout << "\nWelcome to the GradeBook for " << getCourseName() << "!" << endl;
}
private :
int grades[students];
string courseName = "" ;
};
#endif // GRADEBOOK_H
Last edited on Aug 26, 2013 at 7:51pm UTC
Aug 26, 2013 at 7:59pm UTC
I'm going to re-post this code because to read it, I had to re-format it. Indenting is incredibly important because otherwise you can't see your structures. I couldn't tell where one function started and the other ended:
This code was able to compile. Was this an example of the working or not working code? I see that your two members: grades[] and courseName are both private here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
class GradeBook
{
public :
const static int students = 10;
GradeBook( string name, const int gradesArray[])
{
setCourseName( name );
for ( int grade = 0; grade < students; grade++ )
grades[ grade ] = gradesArray[ grade ];
}
void setCourseName(string name)
{
courseName = name;
}
void processGrades()
{
outputGrades();
cout << "\nClass average is " << setprecision(2) << fixed << getAverage() << endl;
cout << "Lowest grade is " << getMinimum() << "\nHighest grade is " << getMaximum() << endl << endl;
outputBarChart();
}
int getMinimum()
{
int lowGrade = 100;
for (int grade = 0; grade < students; grade++)
{
if (grades[grade] < lowGrade)
lowGrade = grades[grade];
}
return lowGrade;
}
int getMaximum()
{
int highGrade = 0;
for ( int grade = 0; grade < students; grade++)
{
if (grades[grade] > highGrade)
highGrade = grades[grade];
}
return highGrade;
}
void outputGrades()
{
cout << "\nThe grades are:\n\n" ;
for (int student = 0; student < students; student++)
cout << "Student " << setw(2) << student + 1 << ": " << setw(3) << grades[student] << endl;
}
void outputBarChart()
{
const int frequencySize = 11;
int frequency[frequencySize] = {};
for (int grade = 0; grade < students; grade++)
frequency[grades[grade]/10]++;
for (int count = 0; count < frequencySize; count++)
{
if (count == 0)
cout << "0-9: " ;
else if (count == 10)
cout << "100: " ;
else
cout << count * 10 << "-" << (count * 10) + 9 << ": " ;
for (int stars = 0; stars < frequency[count]; stars++)
cout << '*' ;
cout << endl;;
}
}
double getAverage()
{
int total = 0;
for (int grade = 0; grade < students; grade++)
total += grades[grade];
return static_cast <double >(total)/students;
}
string getCourseName()
{
return courseName;
}
void displayMessage()
{
cout << "\nWelcome to the GradeBook for " << getCourseName() << "!" << endl;
}
private :
int grades[students];
string courseName = "" ;
};
Aug 26, 2013 at 8:02pm UTC
It would be better if you will post error messages and the statements that are marked as errorneous.
Aug 26, 2013 at 8:04pm UTC
There are no error messages, he specifically stated that this is the code that compiled.
leo255 wrote:Took me a while to figure out that placing private under public got rid of those scoping issues, and I just want to know why, so I can understand what I did wrong.
Aug 26, 2013 at 8:07pm UTC
@L B
There are no error messages, he specifically stated that this is the code that compiled.
leo255 wrote:
Took me a while to figure out that placing private under public got rid of those scoping issues, and I just want to know why, so I can understand what I did wrong.
Does it mean that we shall guess what is the problem?
Aug 26, 2013 at 8:13pm UTC
I think the problem is that when you exchange the public and private sections variable students becomes undefined for array grades. The order of data member declarations is important. So variable students shall be defined before grades[students]
Last edited on Aug 26, 2013 at 8:14pm UTC
Aug 27, 2013 at 12:36am UTC
Thanks for the help, guys!
I apologize for the messy code - I will make sure that further code is formatted more legibly in the future.
Topic archived. No new replies allowed.