Lecture Notes for Advanced Programming II

1 February 2001 - Polymorphism and Templates


  1. polymorphism - abstraction with respect to types.

    1. virtual member functions - supports is-a polymorphism

    2. supports abstraction well, doesn't support re-use as well

  2. templates - explicit type abstraction

    1. warning - templates were crammed into c++

      1. syntax is disgusting

      2. compile-time behavior can be confusing

      3. determining feature interaction can be difficult

  3. function templates

    1. precede the function with template <class T1, ...>

    2. use each of the formal type parameters Ti as if it were a type declaration

    3. the compiler matches a template-function call with the defined templates

      1. the function names must match

      2. the actual argument types must match exactly the formal parameter types

        1. f(1, 1.0, "1") does not match template <class t1,class t2>f(t1 a1, t2 a2, t3 a3) { . . . }

      3. there must be exactly one matching template-function definition

    4. template <class t>
      inline t max(t v1, t v2) {
        return v1 > v2 ? v1 : v2;
        }
      
      void fint(int x, int y) {
        int m = max(x, y);
        }
      
      void fdbl(double x, double y) {
        double m = max(x, y);
        }
      
      void fstr(std::string & x, std::string & y) {
        std::string m = max(x, y);
        }
      

    5. gotchas

      1. the compiler looks only at function arguments to determine types.

        1. each Ti must appear as an argument type - otherwise the compiler can't determine Ti's type.

        2. template <class t>
          t * oops(int i) {
            i++;
            return new t;
            }
          
          void f(void) {
            int * ip = oops(1);
            }
          

      2. type matching is strict - there is no conversion

        1. template <class t>
          void oops(t i, t j) {
            // whatever
            }
          
          void f(void) {
            int i = 3;
            unsigned j = 4;
            oops(i, j)
            }
          

        2. consts are another source of problems, particularly in the stl

      3. watch the operations performed on template-type values - they must be defined

      4. interactions with function overloading, function pointers, ...

  4. class templates

    1. the template header is the same as for functions - except

    2. the formal type parameters can be used throughout the class - no restrictions on number and place

    3. explicit template type instantiation

      1. template <class Etype> class stack {. . .};

      2. stack<int> istk;

    4. where templates get defined - the .h problem

      1. member functions defined within a template class don't need a template prefix

      2. member functions defined outside a template class need a template prefix

      3. do member functions need to be in the same file as the template class declaration - yes and no; the standard allows both, but doesn't say how the compiler discovers the implementation files

  5. other template amusements

    1. non-type parameters - integers and pointers; useful for compile-time size variation; classes only

      1. template <typename Etype, int size> 
        class stack {
          // and so on
          };
        
        void f(void) {
          stack istack;
          // and so on
          }
        

    2. default template parameter values - still need the angle brackes on variable declarations

      1. template <typename Etype = int, int size = 100> 
        class stack {
          // and so on
          };
        
        void f(void) {
          stack cstack;
          stack sstack;
          stack<> istack;
          // and so on
          }
        


This page last modified on 27 February 2001.