/**************************************************************************** ** COPYRIGHT (C): 1997 Cay S. Horstmann. All Rights Reserved. ** PROJECT: Practical OO Development with C++ and Java ** FILE: pstream.cpp ** PURPOSE: persistent streams (chapter 13) ** VERSION 1.0 ** PROGRAMMERS: Cay Horstmann (CSH) ** RELEASE DATE: 3-15-97 (CSH) ** UPDATE HISTORY: ****************************************************************************/ /* Project: Console Application Add files pstream.cpp Additional include directory: \PracticalOOBook\cpplib Settings: Project|Settings|General|Microsoft Foundation Classes|MFC in a shared DLL */ #include "setup.h" #ifndef PRACTICALOO_OLD_INCLUDE #include #else #include #endif #include class Person : public CObject { public: DECLARE_SERIAL(Person); Person(); Person(string, long); virtual void Serialize(CArchive& archive); void print() const; private: string _name; long _age; }; /*.........................................................................*/ IMPLEMENT_SERIAL(Person, CObject, 1) Person::Person() : _age(0) {} CArchive& operator<<(CArchive& archive, string s) { CString c = s.c_str(); archive << c; return archive; } CArchive& operator<<(CArchive& archive, CObject& ob) { if (archive.IsStoring()) ob.Serialize(archive); return archive; } CArchive& operator>>(CArchive& archive, CObject& ob) { if (!archive.IsStoring()) ob.Serialize(archive); return archive; } CArchive& operator>>(CArchive& archive, string& s) { CString c; archive >> c; s = (string)c; return archive; } template void Do_Serialize(C& container, CArchive& archive) { if(archive.IsStoring()) { archive << container.size(); for(C::iterator p = container.begin(); p != container.end(); p++) archive << *p; } else { container = C(); int n; archive >> n; for(int i = 0; i < n; i++) { C::value_type x; archive >> x; container.insert(container.end(), x); } } } Person::Person(string s, long a) : _name(s), _age(a) {} void Person::Serialize(CArchive& archive) { CObject::Serialize(archive); if(archive.IsStoring()) { archive << _name; archive << _age; } else { archive >> _name; archive >> _age; } } void Person::print() const { cout << _name << " " << _age << endl; } /*-------------------------------------------------------------------------*/ class Vehicle : public CObject { public: DECLARE_SERIAL(Vehicle); Vehicle(Person* owner = 0); void drive(Person*); virtual void Serialize(CArchive& archive); void print() const; private: Person* _owner; Person* _driver; }; /*.........................................................................*/ IMPLEMENT_SERIAL(Vehicle, CObject, 1) Vehicle::Vehicle(Person* p) : _owner(p), _driver(0) {} void Vehicle::drive(Person* p) { _driver = p; } void Vehicle::Serialize(CArchive& archive) { CObject::Serialize(archive); if(archive.IsStoring()) { archive << _owner; archive << _driver; } else { archive >> _owner; archive >> _driver; } } void Vehicle::print() const { if (_owner != NULL) _owner->print(); if (_driver != NULL) _driver->print(); } /*-------------------------------------------------------------------------*/ class Company : public CObject // to show how to serialize an STL collection { public: DECLARE_SERIAL(Company); Company(); void add(Person*); virtual void Serialize(CArchive& archive); void print() const; private: #ifndef PRACTICALOO_NEED_ALLOCATORS vector _a; #else vector > _a; #endif }; /*.........................................................................*/ IMPLEMENT_SERIAL(Company, CObject, 1) Company::Company() {} void Company::add(Person* p) { _a.push_back(p); } void Company::Serialize(CArchive& archive) { CObject::Serialize(archive); Do_Serialize(_a, archive); } void Company::print() const { for (int i = 0; i < _a.size(); i++) _a[i]->print(); } /*-------------------------------------------------------------------------*/ int main() { Person* joe = new Person("Joe", 41); Person* carl = new Person("Carl", 17); Vehicle car(joe); Vehicle truck(joe); Company company; car.drive(carl); truck.drive(joe); company.add(carl); company.add(joe); company.add(new Person("Jane", 38)); CFile file1; file1.Open("TEST.DAT", CFile::modeWrite | CFile::modeCreate); CArchive archive1( &file1, CArchive::store); archive1 << car; archive1 << truck; archive1 << company; archive1.Close(); file1.Close(); CFile file2; file2.Open("TEST.DAT", CFile::modeRead); CArchive archive2( &file2, CArchive::load); archive2 >> car; archive2 >> truck; archive2 >> company; cout << "Car:\n"; car.print(); cout << "Truck:\n"; truck.print(); cout << "Company:\n"; company.print(); archive2.Close(); file2.Close(); return 0; }