-->
Page 481
newlicensee.zipcode = "98765"; newlicensee.height = 70; newlicensee.weight = 165; license.month = 1; newlicensee.day = 23; newlicensee.year = 97; newlicensee.license_letter = A; newlicensee.license_number = 567890; newlicensee.display; // and display this instance of the structure }
Note that there are three references to the same display function in Listing 23.13. First, the display function is prototyped as an element within the structure definition. Second, the function is defined. Because the function definition is valid for all instances of the datatype license, the structure's data elements are referenced by the display function without naming any instance of the structure. Finally, when a specific instance of license is created, its associated display function is invoked by prefixing the function name with that of the structure instance.
Listing 23.14 shows the output of this program.
Listing 23.14. Output of the function defined within a structure.
Name: Joe Smith Address: 123 Elm Street Smalltown, AnyState 98765 Height: 70 inches Weight: 160 lbs Date: 1/23/1997 License: A567890
Note that the operator << is the bitwise shift left operator except when it is used with cout. With cout, << is used to move data to the screen. This is an example of operator overloading because the operator can have a different meaning depending on the context of its use. The >> operator is used for bitwise shift right except when used with cin; with cin, it is used to move data from the keyboard to the specified variable.
Overloading and associating functions with data structures lay the groundwork for object- oriented code in C++. Full object orientation is available through the use of the C++ class feature.
A C++ class extends the idea of data structures with associated functions by binding (or encapsulating) data descriptions and manipulation algorithms into new abstract datatypes. When a class is defined, the class type and methods are described in the public interface. The class can also have hidden private functions and data members as well.
Page 482
Class declaration defines a datatype and format, but does not allocate memory or in any other way create an object of the class's type. The wider program must declare an instance, or object, of this type in order to store values in the data elements or to invoke the public class functions. A class is often placed into libraries for use by many different programs, each of which then declares objects that instantiate that class for use during program execution.
Listing 23.15 contains an example of a typical class declaration in C++.
Listing 23.15. Declaring a class in C++.
#include <iostream.h> // declare the Circle class class Circle { private: double rad; // private data member public: Circle (double); // constructor function ~Circle (); // deconstructor function double area (void); // member function - compute area }; // constructor function for objects of this class Circle::Circle(double radius) { rad = radius; } // deconstructor function for objects of this class Circle::~Circle() { // does nothing } // member function to compute the Circle's area double Circle::area() { return rad * rad * 3.141592654; } // application program that uses a Circle object main() { Circle mycircle (2); // declare a circle of radius = 2 cout << mycircle.area(); // compute & display its area }
The example in Listing 23.15 begins by declaring the Circle class. This class has one private member, a floating-point element. The Circle class also has several public members, consisting of three functionsCircle, ~Circle, and area.
The constructor function of a class is a function called by a program in order to construct or create an object that is an instance of the class. In the case of the Circle class, the constructor
Page 483
function (Circle(double)) requires a single parameter, namely the radius of the desired circle. If a constructor function is explicitly defined, it has the same name as the class and does not specify a return value, even of type void.
NOTE |
When a C++ program is compiled, the compiler generates calls to the runtime system, which allocates sufficient memory each time an object of class Circle comes into scope. For example, an object that is defined within a function is created (and goes into scope) whenever the function is called. However, the object's data elements are not initialized unless a constructor function has been defined for the class. |
The deconstructor function of a class is a function called by a program in order to deconstruct an object of the class type. A deconstructor takes no parameters and returns nothing. In this example, the Circle class's deconstructor function is ~Circle.
NOTE |
Under normal circumstances, the memory associated with an object of a given class is released for reuse whenever the object goes out of scope. In such a case, the programmer can omit defining the deconstructor function. However, in advanced applications or where class assignments cause potential pointer conflicts, explicit deallocation of free-store memory might be necessary. |
In addition to the constructor and deconstructor functions, the Circle class contains a public function called area. Programs can call this function to compute the area of Circle objects.
The main program (the main function) in Listing 23.15 shows how an object can be declared. mycircle is declared to be of type Circle and is given a radius of 2.
The final statement in this program calls the function to compute the area of mycircle and passes it to the output function for display. Note that the area computation function is identified by a composite name, just as with other functions that are members of C++ data structures outside of class definitions. This usage underscores the fact that the object mycircle, of type Circle, is being asked to execute a function that is a member of itself, and with reference to itself. The programmer could define a Rectangle class that also contains an area function, thereby overloading the area function name with the appropriate algorithm for computing the areas of different kinds of geometric entities.
A final characteristic of object-oriented languages, and of C++, is support for class inheritance and for polymorphism.