In games, it's not uncommon to define classes that represent points in 2D spaces. Programmers also do the same for points in 3D spaces. However, points in 2D spaces have a lot in common with points in 3D spaces. For instance, they both have x and y coordinates. They both need functions to get and set the x and y coordinates. This suggests that code from the class that represents the 2D point can be reused in the class that represents the 3D point. Listing 6.1 demonstrates how to use inheritance to define 2D and 3D point classes. Listing 6.1. Deriving the point3d class from the point2d class
Listing 6.1 declares a class called point2d on lines 619 that represents a point in a 2D Cartesian coordinate system. As you might expect, it has two constructors as well as member functions, for setting and getting the x and y values of the point. Line 55 shows the definition of a class called point3d, which represents a point in a 3D Cartesian coordinate system. It looks very much like the definition of any other class. However, the name of the point3d class is followed by a colon. After the colon is the keyword public, which is followed by the name point2d. The colon indicates that the point3d class inherits from another class. The keyword public and the name point2d specify that the point3d class inherits from the point2d class, as illustrated in Figure 6.3. Figure 6.3. The point3d class inherits from point2d.
Lines 5862 show that the point3d class has two constructors and a pair of functions for setting and getting the z coordinate of the point in 3D space. Line 64 defines a private data member called z. That is the only member data that the point3d class needs. Note Recall that C++ programmers often refer to parameters as arguments. So a 3-arg constructor is a constructor with three arguments or parameters. If you skip down to line 94 of Listing 6.1, you'll see that the program declares a point3d variable called rightHere. When the program executes this statement, it automatically calls the 3-arg constructor for the point3d class. The code for the 3-arg constructor is given on lines 7379. The constructor's three parameters contain the x, y, and z values passed in from line 94. When the statement on line 94 declares the point3d variable, the program automatically creates an invisible point2d variable inside it. That invisible point2d variable must be initialized whenever the point3d constructor is called. That's why that the last parameter on line 76 is followed by a colon and then a call to the point2d constructor. As Figure 6.4 shows, writing the point3d constructor using this syntax invokes the 2-arg point2d constructor and passes it the parameters xValue and yValue. Figure 6.4. Calling the base class constructor from the derived class.
The 2-arg constructor for the point2d class is on lines 2832. It sets the private data members x and y to the values it receives through its parameter list. When the 2-arg constructor for the point2d class ends, the program jumps back to the body of the 3-arg constructor for the point3d class beginning on line 77. Because the constructor for the point2d class was called on line 76, you can be assured that the invisible point2d object is in a known state before the body of the point3d constructor executes. The only remaining task is to initialize the member data declared in the point3d class. That's exactly what happens on line 78. Program execution now jumps back to line 94 and continues on line 96. At this point, the program calls the X() function using the point3d variable rightHere. However, if you look at the definition of the point3d class, you'll see that there is no function called X(). That is not a problem because point3d inherits the X() function from point2d. Your programs can call functions in base classes using variables of derived typesas this program does on lines 96 and 97 when it calls the X() and Y() functions using the point3d variable. The program in Listing 6.1 demonstrates that the point3d class inherits all of the member data and functions of the point2d class. After you write the point2d class, you don't have to rewrite any of its functionality for the point3d class. It got that automatically through inheritance, which saved you a lot of work. |