previous next Up Title Contents Index

18.5.1 Tulostusmuotoilun palauttaminen

Oletetaanpa tuoterek.cpp - ohjelmassa että hinnat haluttaisiinkin tulostaa kahdella desimaalilla:
	  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?

ali\StreamPr.h - Luokka tulostustarkkuuden asettamiseksi

	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!


previous next Up Title Contents Index