Abstract Classes

 < Day Day Up > 



An abstract class is a class that contains one or more pure virtual function declarations. There can be no instances of an abstract class but you can create an abstract class pointer and assign to it the address of a derived class object. Are you beginning to notice a theme to this object-oriented programming stuff? It is base class pointers pointing to derived class objects in the quest to achieve polymorphic behavior.

By no instances I mean you cannot create an abstract class object. For example, if you have an abstract class named AbstractClass then you cannot do the following:

AbstractClass abs_object; //ERROR! 

Here, an AbstractClass object named abs_object is declared, however, your compiler will complain. On the other hand, you can declare an AbstractClass pointer:

AbstractClass* abs_ptr; //OK

However, if you try to dynamically create an AbstractClass object and assign its address to the pointer your compiler will complain.

abs_ptr = new AbstractClass; //ERROR

If you create another class named DerivedClassOne that inherits from AbstractClass and it provides an implementation for AbstractClass’s pure virtual functions then you can do the following:

abs_ptr = new DerivedClassOne; //OK

Now the base class pointer is being assigned the address of a non-abstract derived class object. Another word for non-abstract is concrete. In this example, DerivedClassOne represents a concrete implementation of AbstractClass.

Let us take a look at an extended example showing abstract classes in use. Figure 13-12 shows a class diagram for a small navy fleet simulation application. The fleet simulation uses three abstract classes, Vessel, Plant, and Weapon. The purpose of each of the abstract classes is to declare an interface that derived classes must implement. The source code for each of the abstract classes appears in examples 13.17 through 13.19.

click to expand
Figure 13-12: Fleet Simulation Class Diagram

Listing 13.17: vessel.h

start example
  1  #ifndef MY_VESSEL_H  2  #define MY_VESSEL_H  3  class Plant;  4  class Weapon;  5  6  class Vessel{  7      public:  8        Vessel(Plant &thePlant, Weapon &theWeapon);  9        virtual ~Vessel(); 10        virtual void LightOff_Plant() = 0; 11        virtual void ShutDown_Plant() = 0; 12        virtual void Train_Weapon() = 0; 13        virtual void Fire_Weapon() = 0; 14        virtual bool Get_Plant_Status() = 0; 15 16      protected: 17        Plant &GetPlant() {return itsPlant;} 18        Weapon &GetWeapon() {return itsWeapon;} 19 20      private: 21        Plant &itsPlant;   22        Weapon &itsWeapon;   23        static int count;   24  }; 25  #endif
end example

Listing 13.18: plant.h

start example
  1   #ifndef MY_PLANT_H  2   #define MY_PLANT_H  3  4   class Plant{  5      public:  6        virtual void LightOff_Plant() = 0;  7        virtual void ShutDown_Plant() = 0;  8        virtual bool Get_Plant_Status() = 0;  9   }; 10   #endif
end example

Listing 13.19: weapon.h

start example
 1   #ifndef MY_WEAPON_H 2   #define MY_WEAPON_H 3 4   class Weapon{ 5       public: 6           virtual void Train_Weapon() = 0; 7           virtual void Fire_Weapon() = 0; 8   }; 9   #endif
end example

Example 13.17 uses several language features you have not seen before. First, on lines 3 and 4 the classes Plant and Weapon are forward declared. You can forward declare a class when you just need the name of the class to be known, rather than all its interface functions. In the Vessel class declaration, the class names Plant and Weapon are simply used to declare constructor parameters and return types. The second language feature used is protected members. The two functions named GetPlant() and GetWeapon() are declared to have protected accessibility. When a derived class inherits from Vessel, it will inherit both of these functions. The private members of Vessel will not be inherited.

All the public interface functions declared in Vessel, with the exception of the constructor, are declared to be virtual. The functions LightOff_Plant(), ShutDown_Plant(), Train_Weapon(), Fire_Weapon(), and Get_Plant_Status() are declared to be pure virtual functions as denoted by their being assigned the value of zero.

Both the Plant and Weapon classes declare an interface only. Notice the lack of an explicitly declared constructor or destructor in each of these classes.

Referring to the fleet simulation class diagram shown in figure 13-12, you can see that a Vessel is comprised of a Plant and a Weapon. The abstract classes declare the type of behavior each of the derived classes must implement. Consider the Weapon class. It declares two interface functions named Train_Weapon() and Fire_Weapon(). In the Weapon class these are pure virtual functions and must be implemented in classes that derive from Weapon. According to the fleet simulation class diagram three classes extend the functionality of Weapon: CIWS (Close In Weapon System), Five_Inch (5” 54 caliber naval gun), and Torpedo. Each of these weapon systems will be aimed and fired in different ways and the source code required to implement that behavior must appear in those concrete classes.

Before discussing how the fleet simulation source code works examine the main.cpp file given in example 13.20 showing the fleet simulation classes in action.

Listing 13.20: main.cpp

start example
  1  #include <iostream>  2  #include "vessel.h"  3  #include "submarine.h"  4  #include "Surface_Ship.h"  5  #include "weapon.h"  6  #include "ciws.h"  7  #include "torpedo.h"  8  #include "five_inch.h"  9  #include "plant.h" 10  #include "nuke_plant.h" 11  #include "steam_plant.h" 12  #include "gasturbine_plant.h" 13 14  int main(){ 15  /*********************************************** 16    Make an array of pointers to base classes  17  ***********************************************/ 18  Vessel *myNavy[2]; 19 20  /************************************************ 21      Make some plants to power the vessels... 22  ************************************************/ 23      Nuke_Plant        Nuke1("Liquid Metal"); 24      Steam_Plant       Steam1(1200); 25      GasTurbine_Plant  GasTurbine("LM5000"); 26 27  /************************************************* 28    Make some weapons... 29  *************************************************/ 30      Torpedo    Torpedo1("MK87", 25); 31      Ciws       Ciws1("MK1001", 5000); 32      Five_Inch  FiveInch1("Super Shot", 400); 33 34  /************************************************** 35    Construct various vessels... 36  **************************************************/ 37      Submarine Sub1(Nuke1, Torpedo1, "SSN 714"); 38      Surface_Ship   Ship1(Steam1, FiveInch1, "Skimmer"); 39 40  /*************************************************** 41  load array with addresses of derrived class objects 42  ***************************************************/ 43      myNavy[0] = &Sub1; 44      myNavy[1] = &Ship1; 45 46  /************************************************** 47  call polymorphic functions via base class pointers 48  **************************************************/ 49 50       for(int i = 0; i<2; i++){ 51           myNavy[i]->LightOff_Plant(); 52           myNavy[i]->Train_Weapon(); 53           myNavy[i]->Fire_Weapon(); 54           myNavy[i]->ShutDown_Plant(); 55       }      56       return 0; 57  }
end example

The results of running this program are shown in figure 13-13. The rest of the source code for the fleet simulation follows with line numbers omitted.


Figure 13-13: Results of Running Example 13.20



 < Day Day Up > 



C++ for Artists. The Art, Philosophy, and Science of Object-Oriented Programming
C++ For Artists: The Art, Philosophy, And Science Of Object-Oriented Programming
ISBN: 1932504028
EAN: 2147483647
Year: 2003
Pages: 340
Authors: Rick Miller

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