< previous page page_925 next page >

Page 925
When a TimeCard object is created, the constructor for its timeStamp member is first invoked. After the timeStamp object is constructed, the body of TimeCard's constructor is executed, setting the id member equal to idNum.
The second constructor shown in the TimeCard class declarationthe default constructorhas no parameters and could be implemented as follows:
TimeCard::TimeCard()
{
    id = 0;
}
In this case, what happened to construction of the timeStamp member object? We didn't include a constructor initializer, so the timeStamp object is first constructed using the default constructor of the Time class, after which the body of the TimeCard constructor is executed. The result is a time card having a time stamp of 0:0:0 and an ID number of 0.
Dynamic Binding and Virtual Functions
Early in the chapter, we said that object-oriented programming languages provide language features that support three concepts: data abstraction, inheritance, and dynamic binding. The phrase dynamic binding means, more specifically, dynamic binding of an operation to an object. To explain this concept, let's begin with an example.
Given the Time and ExtTime classes of this chapter, the following code creates two class objects and outputs the time represented by each.
Time    startTime(8, 30, 0);
ExtTime endTime(10, 45, 0, CST);

startTime.Write();
cout << endl;
endTime.Write();
cout << endl;
This code fragment invokes two different Write functions, even though the functions have the same name. The first function call invokes the Write function of the Time class, printing out three values: hours, minutes, and seconds. The second call invokes the Write function of the ExtTime class, printing out four values: hours, minutes, seconds, and time zone. In this code fragment, the compiler uses static (compile-time) binding of the operation (Write) to the appropriate object. The compiler can easily determine

 
< previous page page_925 next page >