// ---------------------------------------------------------------------------
// A test of virtual functions.
// Paul McNamee 8/5/97
// ---------------------------------------------------------------------------

#include <iostream.h>
#include <string.h>

class Mammal {
  public:
    char name [32] ;
    int has_fur ;
    Mammal ( ) {
      strcpy(name, "no-name") ;
      has_fur = 1 ;
    } ;

    // Print2 is a virtual member function
    virtual void Print2 () {
      cout << "[Mammal: " << name << "]" ;
    } ;

} ;

class Dog : public Mammal {
  public:
    int has_tail ;
    Dog ( ) {
      // Calls Mammal constructor
      has_tail = 1 ;
      strcpy(name, "Betsy") ;
    } ;

    virtual void Print2 () {
      cout << "[Dog: " << name << " has a tail]" ;
    };

} ;

ostream & operator<< (ostream & os, Mammal &m) {
  cout << "Op <<: [Mammal: " << m.name << "]" ;
  return os;
}

ostream & operator<< (ostream & os, Dog &d) {
  cout << "Op <<: [Dog: " << d.name << " has a tail.]" ;
  return os;
}

// Print is a non-member function
void Print (Mammal m) {
  cout << m ;
}

int main () {
  Dog betsy;
  Print(betsy);
  cout << endl;

  Mammal yogi;
  strcpy(yogi.name, "Yogi the bear");

  Print(yogi);
  cout << endl;

  yogi.Print2();
  cout << endl;
    
  betsy.Print2();
  cout << endl;
  
  return 1;
}


// ---------------------------------------------------------------------------
// paulmac@nautilus: CC -o Mammal Mammal.C
// paulmac@nautilus: Mammal
// Op <<: [Mammal: Betsy]
// Op <<: [Mammal: Yogi the bear]
// [Mammal: Yogi the bear]
// [Dog: Betsy has a tail]
// paulmac@nautilus: 
