| < Day Day Up > |
|
Examples 13.1 through 13.4 give the source code for BaseClass and DerivedClassOne contained in four files named baseclass.h, derivedclassone.h, baseclass.cpp, and derivedclassone.cpp.
Listing 13.1: baseclass.h
1 #ifndef BASE_CLASS_H 2 #define BASE_CLASS_H 3 4 class BaseClass{ 5 public: 6 BaseClass(); 7 virtual ~BaseClass(); 8 int getBaseNumber(); 9 int getBaseCount(); 10 11 protected: 12 void b(); 13 14 private: 15 static int count; 16 int its_number; 17 }; 18 #endif
Listing 13.2: derivedclassone.h
1 #ifndef DERIVED_CLASS_H 2 #define DERIVED_CLASS_H 3 #include "baseclass.h" 4 5 class DerivedClassOne : public BaseClass{ 6 public: 7 DerivedClassOne(); 8 virtual ~DerivedClassOne(); 9 int getDerivedOneCount(); 10 int getDerivedOneNumber(); 11 12 private: 13 static int count; 14 int its_number; 15 }; 16 #endif
Listing 13.3: baseclass.cpp
1 #include "baseclass.h" 2 #include <iostream> 3 using namespace std; 4 5 int BaseClass::count = 0; 6 7 BaseClass::BaseClass():its_number(++count){ 8 cout<<"BaseClass object number "<<its_number<<" created."<<endl; 9 cout<<"There are "<<count<<" BaseClass objects."<<endl; 10 } 11 12 BaseClass::~BaseClass(){ 13 cout<<"BaseClass object number "<<its_number<<" destroyed."<<endl; 14 cout<<"There are "<<--count<<" BaseClass objects remaining."<<endl; 15 } 16 17 int BaseClass::getBaseNumber(){ return its_number;} 18 19 int BaseClass::getBaseCount(){return count;} 20 21 void BaseClass::b(){ 22 cout<<"BaseClass protected function called!"<<endl; 23 }
Listing 13.4: derivedclassone.cpp
1 #include "derivedclassone.h" 2 #include "baseclass.h" 3 #include <iostream> 4 using namespace std; 5 6 int DerivedClassOne::count = 0; 7 8 DerivedClassOne::DerivedClassOne():its_number(++count){ 9 cout<<"DerivedClassOne object number "<<its_number<<" created."<<endl; 10 cout<<"There are "<<count<<" DerivedClassOne objects."<<endl; 11 } 12 13 DerivedClassOne::~DerivedClassOne(){ 14 cout<<"DerivedClassOne object number "<<its_number<<" destroyed."<<endl; 15 cout<<"There are "<<--count<<" DerivedClassOne objects remaining."<<endl; 16 } 17 18 int DerivedClassOne::getDerivedOneCount(){return count;} 19 20 int DerivedClassOne::getDerivedOneNumber(){return its_number;}
The behavior of BaseClass is declared by the limited set of public interface functions. All you can do with a BaseClass object is create it, destroy it, get the base number, and get the base count. The protected BaseClass::b() method can only be called from within the class itself or from within the code of a derived class. The BaseClass::b() method simply prints a message to the screen.
It should be noted that the private attributes of BaseClass remain private to BaseClass. They are not available for horizontal access or for access by derived classes. The protected function BaseClass::b() is also closed to horizontal access but is available for inheritance by derived classes.
The keyword virtual is used in front of the destructor. This is done to ensure derived class destructors get called when necessary.
Refer to the declaration for DerivedClassOne shown in example 13.2 above. The class declaration includes a colon followed by the keyword public followed by the name of the class to be used as a base class. In this case the name of the base class is BaseClass. The rest of the DerivedClassOne class declaration is what you have seen in previous chapters. The keyword virtual is applied to the DerivedClassOne destructor although according to the C++ standard doing so is redundant.
Study examples 13.3 through 13.4 to get a feel for what type of behavior these two simple classes will exhibit. When objects of each type are created the constructors will print simple messages to the screen. The same holds true when objects are destroyed. The static data members named count in each class will be used to keep track of how many objects of each type exist. Each class has several accessor functions to get the values of both the static and local data members. The BaseClass::b() function just prints a message to the screen saying that a protected function was called.
Although these two classes do not do much, the simple messages contained in the constructors and destructors will teach us a lot about inheritance. Let us take a look at how these classes would be used in a main() function and examine the results obtained from running such a program. Example 13.5 gives the code showing BaseClass and DerivedClassOne objects being created used in a main() function. Figure 13-2 shows the output when the program is run.
Listing 13.5: main.cpp
1 #include "baseclass.h" 2 #include "derivedclassone.h" 3 #include <iostream> 4 using namespace std; 5 6 int main() 7 { /* create a base class object and call some functions */ 8 BaseClass b1; 9 cout<<"-----------------------------"<<endl; 10 cout<<"Base count is "<<b1.getBaseCount()<<endl; 11 cout<<"This object's number is "<<b1.getBaseNumber()<<endl; 12 cout<<"-----------------------------"<<endl; 13 14 /* create a derived class object and call some base class functions */ 15 DerivedClassOne d1; 16 cout<<"Calling base class function getBaseCount() " 17 <<"from derived class object. "<< d1.getBaseCount()<<endl; 18 cout<<"Calling base class function getBaseNumber() " 19 <<"from derived class object. "<<d1.getBaseNumber()<<endl; 20 cout<<"-----------------------------"<<endl; 21 22 /* create a base class pointer and assign 23 derived class object address */ 24 BaseClass *base_ptr = new DerivedClassOne; 25 26 /* call some base class functions */ 27 cout<<base_ptr->getBaseCount()<<endl; 28 cout<<base_ptr->getBaseNumber()<<endl; 29 cout<<" -----------------------------"<<endl; 30 31 /* now create derived class pointer and call some 32 derived class functions and some base class functions */ 33 DerivedClassOne *derived_ptr = new DerivedClassOne; 34 cout<<derived_ptr->getDerivedOneCount()<<endl; 35 cout<<derived_ptr->getDerivedOneNumber()<<endl; 36 cout<<derived_ptr->getBaseCount()<<endl; 37 cout<<derived_ptr->getBaseNumber()<<endl; 38 cout<<" -----------------------------"<<endl; 39 40 /* destroy the pointers before exiting program */ 41 delete base_ptr; 42 delete derived_ptr; 43 return 0; 44 }
Figure 13-2: Results of Running Example 13.5
A class type can exhibit the behavior of another class type through the mechanism of inheritance. The class whose behavior is inherited is called the base class; the class inheriting the behavior is called the derived class. A public base class function can be called via a derived class object. A base class pointer can be assigned the addresses of a derived class object, however, since the pointer is of a base class type, only the public functions declared in the base class can be called via the pointer. (True for now until you learn how to override base class functions in a later section.) A derived class pointer holding a derived class object address can call both base class and derived class public functions. The previous section presented a quick overview of inheritance but left out a lot of cool stuff. The following sections explore the topic in greater detail.
| < Day Day Up > |
|