Click on the banner to return to the user guide home page.
©Copyright 1996 Rogue Wave Software
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:
BEGIN FILE: 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();
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.
