A megoldásban kihasználjuk, hogy az ifstream és az ofstream típusú objektumok felhasználhatók ott, ahol istream és ostream típusú (ezek a cin és cout típusai) objektumokat várunk.
Így a TwoDimVector.h állomány:
#ifndef TWO_DIM_VECTOR_H
#define TWO_DIM_VECTOR_H // A többszörös beépítés elkerülése
#include<iostream>
class TwoDimVector
{
public:
double x,y;
// Konstruktor
TwoDimVector(double x=0, double y=0){this->x=x; this->y=y;};
// Itt még számos, a kétdimenziós vektorokra jellemző függvény szerepel...
// Megjegyezzük, hogy a későbbiekben a szöveges állományt író/olvasó
// függvényeket túlterhelt << és >> operátorokkal valósítjuk meg, amelyek
// akár ezeket a tagfüggvényeket is hívhatják.
void writeText(std::ostream& os)const;
void readText(std::istream& is);
void writeBinary(std::ostream& os)const;
void readBinary(std::istream& is);
};
#endif /* TWO_DIM_VECTOR_H */
A TwoDimVector.cpp állomány tartalma:
#include "TwoDimVector.h"
using namespace std;
void TwoDimVector::writeText(std::ostream& os)const
{
os << '(' << x << '|' << y << ')';
}
void TwoDimVector::readText(std::istream& is)
{
char c;
// Ideiglenes változókba olvasunk, az objektum állapotát
// csak akkor változtatjuk, ha minden sikerült.
// Így az objektum nem kerülhet inkonzisztens állapotba.
double x, y;
is >> c;
if(c!='(')
{
is.setstate(ios::failbit);
return;
}
is >> x;
is >> c;
if(c!='|')
{
is.setstate(ios::failbit);
return;
}
is >> y;
is >> c;
if(c!=')')
{
is.setstate(ios::failbit);
return ;
}
if(is)
{
this->x = x;
this->y = y;
}
return;
}
void TwoDimVector::writeBinary(std::ostream& os)const
{
// Figyeljük meg, hogy a C++-ban nem az egész struktúrát
// íratjuk ki, mert az implementációtól függően lehet, hogy
// a virtuális függvénytáblát és egyéb adatot is kiír.
// Így az egyszerű típusokat tagonként íratjuk ki (beleértve a tagfüggvény
// nélküli C struktúrát), az objektum tagváltozóknak, pedig az elmentést
// vágző függvényét hívjuk (amely természetesen szintén tagonként dolgozik).
os.write((const char *)&x, sizeof(x));
os.write((const char *)&y, sizeof(y));
}
void TwoDimVector::readBinary(std::istream& is)
{
// Ideiglenes változókba olvasunk, az objektum állapotát
// csak akkor változtatjuk, ha minden sikerült.
// Így az objektum nem kerülhet inkonzisztens állapotba.
double x, y;
is.read((char*)&x, sizeof(x));
is.read((char*)&y, sizeof(y));
if(is)
{
this->x = x;
this->y = y;
}
}
Végül a tesztprogram (TwoDimVectorSample.cpp):
#include "TwoDimVector.h"
#include <iostream>
#include <fstream> // Az állományoknak
using namespace std;
int main()
{
// Létrehozzuk az objektumt
TwoDimVector tdv(2,3);
// Beolvasás tesztelése
cout << "Enter a vector in a form of (x|y): ";
tdv.readText(cin);
if(cin)
{
tdv.writeText(cout);
cout << endl;
}
else
{
cerr << "Error reading vector. Use format (x|y)" << endl;
}
// Tesztelés állományokkal
// (a destruktor lezárja az állományt, csak akkor zárjuk le a close tagfüggvénnyel,
// ha az állományt megakarjuk nyitni.)
// 1. Kiírás bináris állományba
ofstream outFileBinary("vector.bin", ios::out|ios::binary);
tdv.writeBinary(outFileBinary);
outFileBinary.close();
// 2. Beolvasás bináris állományból
ifstream inFileBinary ("vector.bin", ios::in|ios::binary);
TwoDimVector tdv2;
tdv2.readBinary(inFileBinary);
if(inFileBinary)
{
tdv2.writeText(cout); cout << endl;
}
else
{
cerr << "Error reading vector." << endl;
}
// 3. Kiírás szöveges állományba
ofstream outFileText("vector.txt", ios::out);
tdv.writeText(outFileText);
outFileText.close();
// 4. Beolvasás szöveges állományból
ifstream inFileText("vector.txt", ios::in);
tdv2.readText(inFileText);
if(inFileText)
{
tdv2.writeText(cout); cout << endl;
}
else
{
cerr << "Error reading vector." << endl;
}
}