Page 266 - Introduction to Microcontrollers Architecture, Programming, and Interfacing of The Motorola 68HC12
P. 266

8,7 Object-oriented Programming in C++                              243


        template <class T> class Ostack : public Stack<T> { char Index;
             public: Ostack(int i): Stack(i) { }/* constructor, calls base constructor */
             operator T {)                          /* overloaded cast operator */
                  {if(index>(Ptr-Bottom)){Error=l;return 0;} return Ptr[-index];}
             T operator = (T data)                  /* overloaded assignment operator */
              {if(index>(Ptr-Bottom)){Error-Itreturn 0;} return Ptr[-index]=data;J
             T operator [](char data){index=datajreturn *this; }/* index operator */
        };
            The overloaded index operator [ ] illustrates another C++ feature. This overloaded
        operator is called whenever the compiler sees an index [ ] to the right of an object, as in
        s [ 0 ], whether the object and index are on the left or right of an assignment statement
        =. It executes the overloaded operator [ 3 before it executes the overloaded cast or
        overloaded assignment operator. This overloaded operator simply stores what is inside the
        square brackets, 0 in our example, in an object data member index. Then the following
        overloaded cast or assignment operator can use this saved value to supply the offset to
        the stack. Then s [ i ] would read or write the rth element from the top of the stack.
            Now, whenever the compiler sees an object on the left side of an equal sign when it
        has evaluated a number for the expression on the right side and it would otherwise be
        unable to do anything correctly, the compiler looks at your declaration of the overloaded
        assignment operator, to determine that the number will be pushed onto the stack, The
        expression S = 1; will do the same thing as s. push (1);, and *Sptr - 1; will do
        the same thing as Sptr->push{ 1);. Similarly, whenever the compiler sees an object
        anywhere on the right side of an equal sign when it is trying to get a number and it
        would otherwise be unable to do anything correctly, the compiler looks at your
        declaration of the overloaded cast operator to determine that the number will be pulled
        from the stack. The expression i = S; will do the same thing as i = S.pull();,
        and i = *Sptr; will do the same thing as i = Sptr->pull();. Now if a stack S
        returns a temperature in degrees centigrade, you can write an expression like degreeF =
        (S * 9) / 5 + 32; or degreeF = (*Sptr * 9) / 5 + 32;, and the compiler
        will pull an item from the stack each time it runs into the s symbolic name. While
        overloading of operators isn't necessary, it provides a mechanism for simplifying
        expressions to look like common algebraic formulas.
            A derived class usually defines an overloaded assignment operator even if its base
        class has defined an overloaded assignment operator in exactly the same way, because the
        (Metrowerks) C++ compiler can get confused with the "=" sign. If SI and S2 are
        objects of class Cstack<char>, then SI = S2; won't pop an item from S2 and push
        it onto si, as we would wish when we use overloaded assignment and cast operators,
        but "clones" the object, copying device2's contents into devicel as if the object
        were a struct. That is, if SI's class's base class overrides "=" but SI's class itself
        does not override "=", SI = S2; causes S2 to be copied into SI. However, if "=" is
                                      u
        overridden in si's class definition, =" is an overridden assignment operator, and SI =
        S2; pops an item from S2 and pushes it onto SI. The derived class has to override
        "=" to push data. The "=" operator, though useful, needs to be carefully handled. All
        our derived classes explicitly define operator = if "=" is to be overridden.
   261   262   263   264   265   266   267   268   269   270   271