// main.cc  -  Pond main program Listing 1
#include <frog.h>

main()
    {
    PMF_VV pf = &Creature::move;  // bound to a virtual
    Tadpole wiggly("Wiggly");
    Bullfrog croaker("Croaker");
    Pond walden;

    walden.insert(&wiggly);
    walden.insert(&croaker);
    walden.activate( pf ); // Tell all residents to move
    return 0;
    }

 ------------ output -----------------
Wiggly Swimming jerkily
Croaker - I'm jumping

 -----------------------------------
//  Frog.h
#ifndef FROG_H
#define FROG_H
#include <iostream.h>
#include <rw/gslist.h>  // Rogue Wave tools.h++

class Creature
    {
public:
    virtual void move() {} 
    virtual ~Creature() {}
    };

declare(GSlist,Creature)

class Frog : public Creature
    {
protected:
    char *name;
public:
    Frog(char *p="Noname") { name = p; }
    char *Name() { return name; }
    virtual void move() {} 
    virtual ~Frog() {}
    };

class Tadpole : public Frog
    {
public:
    Tadpole(char *name) : Frog(name) {};
    void move(){cout << name << " Swimming jerkily\n";}
    };

class Bullfrog : public Frog
    {
public:
    Bullfrog(char *name) : Frog(name) {};
    void move(){cout << name << " - I'm jumping\n"; }
    };

class Pond
    {
    GSlist(Creature) list;  // singly linked creature list
public:
    // activate takes a ptr to any member func of Frog
    // that takes a void arg and returns a void
    // It turns out move() is the only one so far
    // It iterates over all objects derived from 
    // Creature base class in the Pond
    void activate( void (Creature::*pf) () );
    void insert(Creature *);
    };

// this typedef must be after the class declarations
// it may be useful to simplify declarations in the users program.
// useful for pointing to move(void)
typedef void (Creature::*PMF_VV)();   
#endif
 --------------------------------------------------------
// Frog.cpp
#include <stdlib.h>
#include <frog.h>

void Pond::insert(Creature *f)
    {
    list.insert(f);
    }

void Pond::activate( PMF_VV pmf_vv )
    {
    GSlistIterator(Creature) it(list);
    Creature *resident;
    while ( resident = (Creature *)it() ) 
	{
	(resident->*pmf_vv)();
	}
    }

