Page 265 - Introduction to Microcontrollers Architecture, Programming, and Interfacing of The Motorola 68HC12
P. 265
242 Chapter 8 Programming in C and C++
The following class also exhibits another feature of C++, which is the ability to
write the function member inside the declaration of the class. The function is written in
place of the prototype for the function. This is especially useful when templates are used
with int function members, because otherwise the notation template <class T> and
the class name stack:: would have to be repeated before each function member,
template <class T> class Stack{ private:! *Bottom,*Top,*Ptr;char Error;
public :Stack(int i)
{ Top = ( Bottom = Ptr = (T*)allocate( i ) ) + i ); Error = 0; }
virtual void push (T i){if(Ptr==Top){Error=l; return;} *(++Ptr)=i;}
virtual T pull(void){if(Ptr==Bottom){Error=l; return 0;}return *Ptr—?}
virtual char error ( ) { char i; i = Error; Error = 0; return i; }
};
If you declare Stack<char> S(10); or bless Sptr = new Stack<char>( 10);
then a stack is implemented that stores 8-bit data, but if you declare stack<int> s (10)
or bless Sptr = new stack<int> (10); then a stack is implemented that stores 16-bit
data. Templates permit us to define one generalized class that can be declared or blessed to
handle 8-bit, 16-bit, or 32-bit signed or unsigned data when the program is compiled.
This selection must be made at compile time, because it generates different calls.
Operator overloading means that the same operator symbol generates different
effects depending on the type of the data it operates on. The C compiler already
effectively loads its operators. The + operator generates an ADDB instruction when
adding data of type char, and an ADDD instruction when adding data of type int. What
C++ does but C cannot do is to overload operators so they do different things when an
operand is an object, which depends on the object's definition. In effect, the programmer
can provide a new part of the compiler that generates the code for symbols, depending on
the types of data used with the symbols. For instance, the « operator used for shift can
be used for input or output if an operand is an I/O device. The expression S « a can be
defined to output the character a to the object s, and s » a can be defined to input a
character from the object S and put it into a. This type of operator overloading is used
in I/O streams for inputting or outputting formatted character strings. Without this
feature, we simply have to write our function calls as a=S. Input ( ) and s. Output (a)
rather than s«a or s»a. However, with overloading we write a simpler program; for
instance we can write an I/O stream S « a « " is the value of " « b;
Overloading can also be used to create arithmetic-looking expressions that use function
members to evaluate them. Besides operators like + and -, C++ considers the cast to be
an operator, as well as the assignment =. In the following example, we overload the cast
operator as shown by operator T () ; and the assignment operator as shown by T
operator = (T); . T will be a cast, like char, so operator T {}; will become
operator char {) ; whenever the compiler has an explicit cast like (char} i, where
i is an object, or an implicit cast where object i appears in an expression needing a
char, the compiler calls the user-defined overloaded operator to perform the cast
function. Similarly, wherever the compiler has calculated an expression that has a char
value but the assignment statement has an object i on its left, the compiler calls up the
overloaded = operator the user specifies with T operator = (T);