Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys

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;
	  ios::fmtflags 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!


Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys