Protected Members


C++ has a way for base classes to provide derived classes with access to some of their private member data or functions. By changing private member data or functions to protected, all derived classes can access them. Listing 6.2 gives an example.

Listing 6.2. Protected member data

 1   #include <cstdlib> 2   #include <iostream> 3 4   using namespace std; 5 6   class base 7   { 8   protected: 9       int anInt; 10  }; 11 12  class derived : public base 13  { 14  public: 15      void AFunction(int theInt); 16  }; 17 18  inline void derived::AFunction(int theInt) 19  { 20      anInt = theInt; 21 22      cout << anInt << endl; 23  } 24 25  int main(int argc, char *argv[]) 26  { 27      derived temp; 28 29      temp.AFunction(5); 30 31      system("PAUSE"); 32      return EXIT_SUCCESS; 33  } 

This short program defines two classes. One is called base and the other is named derived. On line 8, access to the single item of member data in base is specified using the keyword protected rather than private. If anInt was specified as private rather than protected, it could be accessed only by functions that are members of the base class. Because this example uses protected instead, the member function in the derived class can directly access anInt. This is demonstrated on lines 2022.

It is important to note that only functions in classes derived from base can access anInt directly. Other functions do not have access. It would be a mistake, for example, to put the statement

 temp.anInt = 5; 


in the function main(). The main() function is not a member of a class derived from base. Therefore, it does not have access to protected items in base.

In general, I recommend that you avoid the use of protected member data. It can easily be used to bypass the normal access mechanisms you build into your classes. In other words, when you provide a protected data member in a base class, a derived class can contain a function that sets that data member to an invalid value. It is my experience that this actually happens all too often. One programmer writes a class that contains a protected data member and another uses the class in unexpected ways by setting the protected data member to an unusual value.

If you find that you need to provide derived classes with access to a base class's private data, there's a better approach, as demonstrated in Listing 6.3. Instead of providing protected member data, provide protected member functions to get and set the data.

Listing 6.3. A better style of protected access

 1   #include <cstdlib> 2   #include <iostream> 3 4   using namespace std; 5 6   class base 7   { 8   protected: 9       void AnInt(int intValue); 10      int AnInt(); 11 12  private: 13      int anInt; 14  }; 15 16 17  inline void base::AnInt(int intValue) 18  { 19      if (intValue >= -10) 20      { 21          anInt = intValue; 22      } 23      else 24      { 25          anInt = -10; 26      } 27  } 28 29  inline int base::AnInt() 30  { 31      return (anInt); 32  } 33 34 35  class derived : public base 36  { 37      public: 38      void AFunction(int theInt); 39  }; 40 41  inline void derived::AFunction(int theInt) 42  { 43      AnInt(theInt); 44 45      cout << AnInt() << endl; 46  } 47 48  int main(int argc, char *argv[]) 49  { 50      derived temp; 51 52      temp.AFunction(5); 53 54      system("PAUSE"); 55      return EXIT_SUCCESS; 56  } 

In this version of the program, the member data is private rather than protected. Also, the base class adds two protected functions. These functions set and get the value of anInt, respectively. If you look at derived::AFunction() on lines 4146, you can see that it must access the information in anInt tHRough the protected member functions. It no longer has direct access to anInt. Classes that are derived from base can use the overloaded AnInt() functions to set or get the value of anInt. Therefore, derived::AFunction() can do everything it could do in the previous version. However, because all access to the private data member anInt must occur through the protected AnInt() functions, AnInt() can use an if-else statement to prevent anInt from being set to an invalid value, as shown in lines 1926.

Tip

I strongly recommend that, rather than create classes with protected member data, you provide protected member functions to get and set the data. This approach helps ensure that member data in the base class can never be set to invalid values.




Creating Games in C++(c) A Step-by-Step Guide
Creating Games in C++: A Step-by-Step Guide
ISBN: 0735714347
EAN: 2147483647
Year: N/A
Pages: 148

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