ostream &tulosta(ostream &os) const {
os.precision(2); os.setf(ios::left | ios::showpoint | ios::fixed );
os << setw(20) << nimike << " " << setiosflags(ios::right)
<< setw(10) << hinta << " "
<< setw(4) << kpl;
return os;
}
...
ostream &operator<<(ostream &os,const cTuote &tuote) {
return tuote.tulosta(os); }
Nyt tietysti voisi olla ohjelmoijalle yllätys, jos hän kutsuisi
cTuote tuote("Volvo|23700|1");
const double pi = 3.14159265;
cout.precision(6);
cout << pi << '\n';
cout << tuote << '\n';
cout << pi << '\n';
ja jälkimmäinen piin arvo tulostuisikin vain kahdella desimaalilla.
Tämän vuoksi pitäisi alkuperäiset tulostusasetukset
palauttaa, mikäli niitä muutetaan.
ostream &tulosta(ostream &os) const {
long oldf = os.setf(ios::left | ios::showpoint | ios::fixed );
int olddes = os.precision(2);
... tulostusta ...
os.precision(olddes); os.flags(oldf);
return os;
}
Mutta kuka tämän jaksaa tehdä kerrasta toiseen?Entäpä jos teemmekin luokan cStreamPre (stream precision):
ostream &tulosta(ostream &os) const {
cStreamPre pre(os,2);
... tulostusta ...
return os;
}
ja nyt piikin tulee taas pyydetyllä 6:lla desimaalilla molemmilla
kerroilla! Miten?
class cStreamPre {
ostream &os;
long oldf;
int oldp;
public:
cStreamPre(ostream &aos=cout,int npre=1,long flags=0) : os(aos) {
oldf = os.setf(ios::showpoint | ios::fixed | flags);
oldp = os.precision(npre);
}
~cStreamPre() { os.flags(oldf); os.precision(oldp); }
};
Luokan muodostaja tallettaa olion attribuutteihin tulostuksen muotoilun ennen
kuin muotoiluja on muutettu. Kun syntyneen olion vaikutusalue lakkaa, eli
poistutaan siitä ohjelmalohkosta jossa olio on syntynyt (auto),
kutsutaan olion hajottajaa, joka palauttaa alkuperäiset arvot. Nyt
ohjelmoijan tarvitsee vain antaa olion syntyä automaattisesti
cStreamPre pre(os,2);lohkon alussa. Ja tämähän saadaan vähemmällä kirjoittamisella kuin tarkkuuden muuttaminen normaalisti:
os.precision(2); os.setf(ios::left | ios::showpoint | ios::fixed );Huomattakoon, että "temppu" toimii vaikka kesken tulostuksen poistuttaisiin ylimääräisellä return--lauseella. Samoin "temppu" toimii, vaikka tulostuksen sisällä kutsuttaisiin toista samalla tavalla toteutettua tulostusta!