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.
© Copyright Rogue Wave Software, Inc. All Rights Reserved.
Rogue Wave and SourcePro are registered trademarks of Rogue Wave Software, Inc. in the United States and other countries. All other trademarks are the property of their respective owners.
Contact Rogue Wave about documentation or support issues.