Complete Listing for Class Bus
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 is 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 {
RW_DECLARE_COLLECTABLE_CLASS(USER_MODULE, Bus)
public:
Bus();
Bus(int busno, const RWCString& driver);
~Bus();
// Inherited from class "RWCollectable":
Rwspace binaryStoreSize() const;
int compareTo(const RWCollectable*) const;
bool 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 {
RW_DECLARE_COLLECTABLE_CLASS(USER_MODULE, Client)
Client();
Client(const char* name);
Rwspace binaryStoreSize() const;
int compareTo(const RWCollectable*) const;
bool 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>
#include <fstream>
using namespace std;
RW_DEFINE_COLLECTABLE_CLASS_BY_ID(USER_MODULE, 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;
}
bool
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 //////////////
RW_DEFINE_COLLECTABLE_CLASS_BY_NAME(USER_MODULE, 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_);
}
bool
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_;
}
int main() {
Bus theBus(1, "Kesey");
theBus.addPassenger("Bjorn");
theBus.addPassenger("Michael");
theBus.addCustomer("Terry");
theBus.addCustomer("Dave");
{ // 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.