Encapsulation in Action Using C


Encapsulation in Action Using C++

Let s take a look at how the public and private access specifiers are used in a C++ program. The following example defines a class called Student whose attributes are a student ID, student name , and the student s graduation status. Two member functions are defined in the Student class. (We ll use the term member function in place of the term procedure in this section because a procedure in C++ is called a function.)

Functions associated with a class are called member functions . The first member function is Write() , and it assigns values to attributes. The other member function is Display() , which displays values stored in attributes. This is the same Display() member function you learned about in the previous section. Neither member functions return a value.

We want attributes of the Student class to be accessed only through the Write() and Display() functions and not directly within the program by using an instance of the Student class. That is, the only way to store a value in an attribute or to display attributes is by calling a member function of the Student class.

To make this happen, we ll need to place the definition of the Write() and Display() functions beneath the public access specifier and then place attributes below the private access specifier .

Note  

In the real world, class definitions are typically contained in a class library that is made accessible to a program during the linking process. The programmer doesn t have direct access to the class definition. Instead, the programmer is provided with documentation of public and protected attributes and member functions, when available, of the class definition. In this example, the programmer would receive documentation on how to use the Write() member function and the Display() member function of the Student class. The programmer would not know anything about the attributes of the Student class because the attributes are in the private access specifier and cannot be directly accessed by the programmer from within the program. In the real world, the class documentation mentions private members to help a programmer understand how the public function accesses them.

Inside the Write() Member Function

You ll remember from Figure 3-1 that the Student class has two behaviors that are encoded in the form of the Write() member function and the Display() member function. The Write() member function writes values to attributes of the class, and the Display() member function displays those attributes.

The Write() member function has four arguments in its argument list, as shown here:

 Write(int ID, int Grad, char Fname[], char Lname[]) 

The first two arguments are integers representing the student ID and an indicator of whether the student has graduated . The other two arguments are character arrays that represent the first name and last name of the student.

Notice that these arrays don t have a definitive size, as indicated by the empty brackets. As you ll recall from your C++ programming class, the size of these arrays is set when the student s first and last names are received by the member function. The size then becomes the same size as the student s first and last name.

The body of the definition of the Write() member function assigns values of the argument list to attributes. An assignment statement is used to assign values to integer attributes. The strcpy () function is called to assign the values of the Fname and Lname character arrays, which are strings, to the corresponding attributes.

Inside the Display() Member Function

The Display() member function, shown here, reads values of attributes and displays each of them on the screen. A series of insertion operators (<<) form a cascade of strings and attributes to create the text that is shown. (Refer to C++ Demystified , also by McGraw-Hill/Osborne, to brush up on your C++ programming terms.)

 void Display(){ 
cout << "Student: " << m_ID << " " << m_First << " " << m_Last << "
Graduated:
" << m_Graduation << endl;
}

Names of attributes are dispersed throughout string literals. String literals are labels for the attributes when they are displayed. The insertion operator sends the output to the instance of cout , which references standard out. Standard out is typically the screen.

Inside the main() Function

An instance of the Student class called myStudent is declared in the first statement of the main() function. You ll recall from your C++ programming course that the main() function is the entry point into a C++ program.

The second statement uses the name of the instance to call the Write() member function. The parameter list of the Write() member function consists of the student s ID, an integer indicating whether or not the student has graduated, and the student s first name and last name. We ll use 1 to indicate that the student has graduated and 0 to indicate that the student hasn t graduated yet.

The last statement in the main() function uses the name of the instance to call the Display() member function, which displays the value of attributes on the screen.

A compiler error occurs if the programmer attempts to directly access attributes of the Student class because attributes are within the private access specifier section of the class definition.

 #include <string> 
#include <iostream>
using namespace std;
class Student
{
public:
void Write(int ID, int Grad, char Fname[], char Lname[]) {
m_ID = ID;
m_Graduation = Grad;
strcpy(m_First,Fname);
strcpy(m_Last, Lname);
}
void Display(){
cout << "Student: " << m_ID << " " << m_First << " "
<< m_Last << " Graduated: " << m_Graduation << endl;
}
private:
int m_ID, m_Graduation;
char m_First[16], m_Last[16];
};
void main()
{
Student myStudent;
myStudent.Write(10, 1,"Bob","Smith");
myStudent.Display();
}

If you use an instance to access a private or protected member of a class, you ll experience a compiler error. In the last statement of the next example, the program tries to access the m_ID member of the Student class. The m_ID member is a private member and can only be accessed by a member function of the Student class.

You ll receive the following error message if you try to compile this example:

 'm_ID' : cannot access private member declared in class 'Student' 
#include <string>
#include <iostream>
using namespace std;
class Student
{
public:
void Write(int ID, int Grad, char Fname[], char Lname[]) {
m_ID = ID;
m_Graduation = Grad;
strcpy(m_First,Fname);
strcpy(m_Last, Lname);
}
void Display(){
cout << "Student: " << m_ID << " " << m_First << " " << m_Last
<< " Graduated: " << m_Graduation << endl;
}
private:
int m_ID, m_Graduation;
char m_First[16], m_Last[16];
};
void main()
{
Student myStudent;
myStudent.Write(10, 1,"Bob","Smith");
myStudent.Display();
myStudent.m_ID = 2;
}

Protected Access Specifier in Action

You learned previously in this chapter that a class can inherit attributes and procedures of another class that are defined within the public access specifier or protected access specifier of the class. You ll learn all the nitty-gritty about inheritance in Chapter 5, but let s take a glimpse of what s to come by reviewing an example of the protected access specifier.

The following example defines two classes: Student and GradStudent . The Student class defines attributes and procedures of any student, which you saw in the previous example. The GradStudent class defines attributes and procedures of a graduate student. A graduate student is a student; therefore, a graduate student has the attributes and procedures of a student. In addition, a graduate student has attributes and procedures that are unique to only a graduate student.

This is a perfect situation to have the GradStudent class inherit the Student class. In C++, you indicate that a class inherits from another class by placing a colon and the name of the inherited class in the class definition, as shown in this example. Notice that a colon and the name of the Student class follow the GradStudent class name. This tells the computer that the GradStudent class inherits the Student class.

Also notice that attributes of the Student class are placed in the protected access specifier section of the Student class definition. This makes the attributes available to member functions defined in the Student class and member functions defined in the GradStudent class, but those attributes cannot be directly accessed by other parts of the program.

 #include <string> 
#include <iostream>
using namespace std;
class Student
{
public:
void Write(int ID, int Grad, char Fname[], char Lname[]) {
m_ID = ID;
m_Graduation = Grad;
strcpy(m_First,Fname);
strcpy(m_Last, Lname);
}
void Display(){
cout << "Student: " << m_ID << " " << m_First << " " << m_Last
<< " Graduated: " << m_Graduation << endl;
}
protected:
int m_ID, m_Graduation;
char m_First[16], m_Last[16];
};
class GradStudent : Student
{
public:
void Write(int ID, int Grad, char Fname[], char Lname[], int yrGrad,
char unSch[], char major[]) {
m_ID = ID;
m_Graduation = Grad;
YearGraduated = yrGrad;
strcpy(m_First,Fname);
strcpy(m_Last, Lname);
strcpy(m_UndergradSchool,unSch);
strcpy(m_Major, major);
}
void Display(){
cout << "Student: " << m_ID << " " << m_First << " " << m_Last
<< " Graduated: " << m_Graduation << " " << m_UndergradSchool
<< " " << m_Major << " " << YearGraduated<< endl;
}
private:
int YearGraduated;
char m_UndergradSchool[80];
char m_Major[80];
};
void main()
{
GradStudent myStudent;
myStudent.Write(10, 1,"Bob","Smith", 2000,"Columbia University", "CS");
myStudent.Display();
}

Inside the GradStudent Class

The GradStudent class definition defines its own versions of the Write() member function and the Display() member function. We use the term member function instead of procedure because this example is written in C++, where procedures are called functions and functions defined in a class are called member functions .

There is a practical reason for having to redefine these member functions. The Write() member function and the Display() member function of the Student class cannot write values to or display attributes of the GradStudent class. The redefined member functions in the GradStudent class write values to attributes and display attributes defined both in the Student class and in the GradStudent class.

Notice that the redefined member functions use attributes defined in the Student class as if it was defined in the GradStudent class. This is made possible because the GradStudent class inherits attributes defined in the protected access specifier section of the Student class.

The GradStudent class defines its own attributes that are placed in the private access specifier section of the class. Only member functions defined in the GradStudent class can access these attributes. The Student class does not have access to member functions and attributes defined in the GradStudent class. You ll learn the reason for this in Chapter 5.

The attributes defined in the GradStudent class are used to store the year that the student was awarded an undergraduate degree. Other attributes are used to store the name of the school that awarded the degree and the student s undergraduate major.

The main function in this example is nearly identical to the main function of the previous example with two exceptions. First, an instance of the GradStudent class is declared rather than an instance of the Student class because the program is focused on a graduate student rather than any kind of student. The other exception is that the program calls member functions of the GradStudent class.

How does the computer know to use the Write() and Display() member functions defined in the GradStudent class and not those defined in the Student class?

The answer: By default, the computer uses a member function defined in the GradStudent class whenever there is a conflict with a member function named in the Student class.




OOP Demystified
OOP Demystified
ISBN: 0072253630
EAN: 2147483647
Year: 2006
Pages: 130

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net