Classes


Most of the previous discussion on structures applies also to classes. Indeed, for the most part you can simply substitute the class keyword for the struct keyword when declaring the class.

However, there is an important difference between structures and classes. To illustrate that difference, let s run the following program which is identical to the one in the earlier section, Passing Structures as Function Arguments, with one exception: the class keyword has been substituted for the struct keyword when declaring the Person class:

 #include <iostream> #include <string> using namespace std; class Person {  string name;   int height; }; void setValues(Person&); void getValues(const Person&); int main () {  Person p1;  setValues(p1);   cout << "Outputting person data\n";  cout << "======================\n";  getValues(p1);  return 0; } void setValues(Person& pers) {  cout << "Enter person's name: ";  getline(cin, pers.name);  cout << "Enter height in inches: ";  cin >> pers.height;   cin.ignore(); } void getValues(const Person& pers) {  cout << "Person's name: " << pers.name << endl;   cout << "Person's height in inches is: " << pers.height << endl; } 

The unfortunate result is a number of compiler errors in getValues and setValues. Each reference to pers.name and pers.height is flagged by an error message that you are unable to access a private member declared in class Person. What happened ?

The reason why we experienced compiler errors when Person is a class but not when it is a structure is that, by default, member variables of a class are private, whereas member variables of a structure are public.

A public member variable may be accessed anywhere in the program. Therefore, when Person was a structure instead of a class, the compiler did not object when we attempted to access pers.name and pers.height in getValues and setValues because name and height are public variables.

By contrast, a private member variable may be accessed only by a member function of the same class. The getValues and setValues functions are not member functions of the Person class, as a Person constructor would be, for example. Since the getValue s and setValues functions are outside the class, they are not permitted to access the Person private member variables name and height. The result of this impermissible attempt is a compiler error.

The solution is to create public member functions to read from, and write to, the private member variables. These member functions are public so they can be accessed outside the class.

In the following program, the getName member function reads from the name member variable and the setName member function writes to it. Similarly, the getHeigh t member function reads from the height member variable, and the setHeight member function writes to it.

 #include <iostream> #include <string> using namespace std; class Person {  private:  string name;   int height;   public:  string getName() const;  void setName(string);  int getHeight() const;  void setHeight(int); };  string Person::getName() const  { return name; }  void Person::setName(string s)  {   if (s.length() == 0)  name = "No name assigned";  else  name = s;   }  int Person::getHeight() const  { return height; }  void Person::setHeight(int h)  {   if (h < 0)  height = 0;  else  height = h;   } void setValues(Person&); void getValues(const Person&); int main () {  Person p1;  setValues(p1);   cout << "Outputting person data\n";  cout << "======================\n";  getValues(p1);  return 0; } void setValues(Person& pers) {  string str;  int h;  cout << "Enter person's name: ";  getline(cin,str);  pers.setName(str);  cout << "Enter height in inches: ";  cin >> h;  cin.ignore();  pers.setHeight(h); } void getValues(const Person& pers) {  cout << "Person's name: " << pers.getName() << endl;   cout << "Person's height in inches is: " << pers.getHeight() << endl;  } 
Note  

The earlier section on Passing Structures as Function Arguments explains why the getValues function passes its argument by reference and why that argument is preceded by the const keyword. Similarly, the getName and getHeight member functions are followed by the const keyword to indicate they will not change the values of the Person object that calls them.

Now the program compiles and runs and provides the expected output:

 Enter person's name: Jeff Kent Enter height in inches: 72 Outputting person data ====================== Person's name: Jeff Kent Person's height in inches is: 72 

While this program works fine, you legitimately may wonder why we went to the trouble of using public member functions to read from, and write to, private member variables, rather than just make the member variables public.

When Person was a structure instead of a class, there was nothing in the structure to prevent invalid values from being assigned to its member variables since the structure permitted direct access to these variables from outside the structure. Therefore, the assigned input could be a blank name and negative height:

 Enter person's name: Enter height in inches: -5 Outputting person data ====================== Person's name:  Person's height in inches is: -5 

However, when Person is a class, the member functions could perform input validation before assigning the input value to the member variable. In this regard, the setName member function checks if the input string is blank, and if it is, assigns No name assigned rather than a blank string to the name member variable. Similarly, the setHeight member function checks if the input number is negative, and if it is, assigns zero instead of the negative number to the height member variable. The following sample input and output demonstrates this:

 Enter person's name: Enter height in inches: -5 Outputting person data ====================== Person's name: No name assigned Person's height in inches is: 0 

This demonstrates another aspect of OOP, encapsulation or information-hiding. The applicability of information hiding is that the class data or information, contained in its member variables, is hidden from the outside world and access to them is restricted to member functions. Encapsulation applies because a member variable is packaged together with the member functions that read or write to it.

One benefit, as this example demonstrated, is for the member functions that write to member variables to perform input validation. Another benefit could be for the member functions that read from member variables and return their values to restrict read access to only those users who in the particular system have the right to access that information.  




C++ Demystified(c) A Self-Teaching Guide
C++ Demystified(c) A Self-Teaching Guide
ISBN: 72253703
EAN: N/A
Year: 2006
Pages: 148

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