Rogue Wave banner
Previous fileTop of documentContentsIndexNext file

15.3 Summary

In general, you may not have to supply definitions for all of these virtual functions when designing your own class. For example, if you know that your class will never be used in sorted collections, then you do not need a definition for compareTo(). Nevertheless, it is a good idea to supply definitions for all virtual functions anyway: that's the best way to encourage code reuse!

Here then, is the complete listing for our class Bus:

BUS.H:

#ifndef __BUS_H__
#define __BUS_H__

#include <rw/rwset.h>
#include <rw/collstr.h>

class Bus : public RWCollectable  {
  RWDECLARE_COLLECTABLE(Bus)

public:

  Bus();
  Bus(int busno, const RWCString& driver);
  ~Bus();

  // Inherited from class "RWCollectable":
  Rwspace      binaryStoreSize() const;
  int          compareTo(const RWCollectable*) const;
  RWBoolean    isEqual(const RWCollectable*) const;
  unsigned     hash() const;
  void         restoreGuts(RWFile&);
  void         restoreGuts(RWvistream&);
  void         saveGuts(RWFile&) const;
  void         saveGuts(RWvostream&) const;

  void         addPassenger(const char* name);
  void         addCustomer(const char* name);
  size_t       customers() const;
  size_t       passengers() const;
  RWCString    driver() const     {return driver_;}
  int          number() const     {return busNumber_;}

private:

  RWSet        customers_;
  RWSet*       passengers_;
  int          busNumber_;
  RWCString    driver_;
};

class Client : public RWCollectable  {
  RWDECLARE_COLLECTABLE(Client)
  Client();
  Client(const char* name);
  Rwspace      binaryStoreSize() const;
  int          compareTo(const RWCollectable*) const;
  RWBoolean    isEqual(const RWCollectable*) const;
  unsigned     hash() const;
  void         restoreGuts(RWFile&);
  void         restoreGuts(RWvistream&);
  void         saveGuts(RWFile&) const;
  void         saveGuts(RWvostream&) const;
private:
  RWCString    name_;
//ignore other client information for this example
};
#endif

BUS.CPP:

#include "bus.h"
#include <rw/pstream.h>
#include <rw/rwfile.h>
#ifdef __GLOCK__
#  include <fstream.hxx>
#else
#  include <fstream.h>
#endif

RWDEFINE_COLLECTABLE(Bus, 200)

Bus::Bus() :
  busNumber_  (0),
  driver_     ("Unknown"),
  passengers_ (rwnil)
{}

Bus::Bus(int busno, const RWCString& driver) :
  busNumber_  (busno),
  driver_     (driver),
  passengers_ (rwnil)
{}

Bus::~Bus()  {
  customers_.clearAndDestroy();
  delete passengers_;
}

RWspace
Bus::binaryStoreSize() const  {
  RWspace count = RWCollectable::binaryStoreSize() +
    customers_.recursiveStoreSize() +
    sizeof(busNumber_) +
    driver_.binaryStoreSize();

 if (passengers_)
     count += passengers_->recursiveStoreSize();
   else
     count += RWCollectable::nilStoreSize();

   return count;
}


int
Bus::compareTo(const RWCollectable* c) const  {
  const Bus* b = (const Bus*)c;
  if (busNumber_ == b->busNumber_) return 0;
  return busNumber_ > b->busNumber_ ? 1 : -1;
}

RWBoolean
Bus::isEqual(const RWCollectable* c) const  {
  const Bus* b = (const Bus*)c;
  return busNumber_ == b->busNumber_;
}

unsigned
Bus::hash() const  {
  return (unsigned)busNumber_;
}

size_t
Bus::customers() const  {
  return customers_.entries();
}

size_t
Bus::passengers() const    return passengers_ ? passengers_->entries() : 0;
}

void 
Bus::saveGuts(RWFile& f) const  {
  RWCollectable::saveGuts(f);    // Save base class
  f.Write(busNumber_);           // Write primitive directly
  f << driver_ << customers_;    // Use Rogue Wave provided versions
  f << passengers_;        // Will detect nil pointer automatically
}

void 
Bus::saveGuts(RWvostream& strm) const  {
  RWCollectable::saveGuts(strm);   // Save base class
  strm << busNumber_;              // Write primitives directly
  strm << driver_ << customers_;   // Use Rogue Wave 
                                   // provided versions
  strm << passengers_;     // Will detect nil pointer automatically
}

void Bus::restoreGuts(RWFile& f)  {
  RWCollectable::restoreGuts(f);  // Restore base class
  f.Read(busNumber_);             // Restore primitive
  f >> driver_ >> customers_;     // Uses Rogue Wave
                                  // provided versions

  delete passengers_;             // Delete old RWSet
  f >> passengers_;               // Replace with a new one
}

void Bus::restoreGuts(RWvistream& strm)  {
  RWCollectable::restoreGuts(strm); // Restore base class
  strm >> busNumber_ >> driver_ >> customers_;

  delete passengers_;             // Delete old RWSet
  strm >> passengers_;            // Replace with a new one
}

void
Bus::addPassenger(const char* name)  {
  Client* s = new Client(name);
  customers_.insert( s );

  if (!passengers_)
    passengers_ = new RWSet;

  passengers_->insert(s);
}

void
Bus::addCustomer(const char* name)  {
  customers_.insert( new Client(name) );
}

///////////////    Here are Client methods //////////////
RWDEFINE_NAMED_COLLECTABLE(Client,"client")

Client::Client() {} // Uses RWCString default constructor

Client::Client(const char* name) : name_(name) {}

RWspace
Client::binaryStoreSize() const {
  return name_->binaryStoreSize();
}

int
Client::compareTo(const RWCollectable* c) const  {
  return name_.compareTo(((Client*)c)->name_);
}

RWBoolean
Client::isEqual(const RWCollectable* c) const  {
  return name_ == *(Client*)c;
}

unsigned
Client::hash() const  {
  return name_.hash();
}

void
Client::restoreGuts(RWFile& f)  {
  f >> name_;
}

void
Client::restoreGuts(RWvistream& vis)  {
  vis >> name_;
}

void
Client::saveGuts(RWFile& f) const  {
  f << name_;
}

void
Client::saveGuts(RWvostream& vos) const  {
  vos << name_;
}


main()  {
  Bus theBus(1, "Kesey");
  theBus.addPassenger("Frank");
  theBus.addPassenger("Paula");
  theBus.addCustomer("Dan");
  theBus.addCustomer("Chris");

  { // block controls lifetime of stream
    ofstream f("bus.str");
    RWpostream stream(f);
    stream << theBus;      // Persist theBus to an ASCII stream
  }

  {
    ifstream f("bus.str");
    RWpistream stream(f);
    Bus* newBus;
    stream >> newBus;      // Restore it from an ASCII stream

    cout << "Bus number " << newBus->number() 
         << " has been restored; its driver is " 
         << newBus->driver() << ".\n";
    cout << "It has " << newBus->customers() 
         << " customers and "
        << newBus->passengers() << " passengers.\n\n";

    delete newBus;
  }

  return 0;
}

Program Output:

Bus number 1 has been restored; its driver is Kesey.
It has 4 customers and 2 passengers.


Previous fileTop of documentContentsIndexNext file
©Copyright 1999, Rogue Wave Software, Inc.
Send mail to report errors or comment on the documentation.