Programowanie. Teoria i praktyka z wykorzystaniem C++
Programowanie. Teoria i praktyka z wykorzystaniem C++ Programowanie. Teoria i praktyka z wykorzystaniem C++
6.8. STRUMIENIE TOKENÓW 207 dla uytkowników i prywatnym dla implementatorów jest doskonaym narzdziem wspomagajcym strukturalizacj kodu. Interfejs publiczny powinien zawiera wycznie to, co jest uytkownikowi potrzebne, a wic najczciej zestaw funkcji, take konstruktorów sucych do inicjowania obiektów. Implementacj prywatn stanowi kod tych publicznych funkcji. Najczciej s to dane i funkcje wykonujce skomplikowane dziaania, o których uytkownik nie musi wiedzie i których nie musi bezporednio uywa. Rozszerzymy troch nasz typ Token_stream. Jakie wymagania powinien spenia? Bez wtpienia potrzebujemy funkcji get() i putback(), poniewa to one byy powodem, dla którego w ogóle wymylilimy co takiego jak strumie tokenów. Zadaniem typu Token_stream jest wytwarzanie tokenów ze znaków wczytywanych na wejciu. Zatem nasz strumie musi wczytywa dane ze strumienia cin. Oto najprostsza moliwa wersja typu Token_stream: class Token_stream { public: Token_stream(); // Tworzy obiekt typu Token_stream, który wczytuje dane ze strumienia cin. Token get(); // Daje token (obiekt typu Token). void putback(Token t); // Wkada token z powrotem. private: // szczegóy implementacyjne }; To wszystko, czego uytkownik potrzebuje do korzystania z typu Token_stream. Dowiadczony programista mógby si zastanawia, dlaczego cin jest jedynym moliwym ródem znaków — przypominamy, e zdecydowalimy si na razie pobiera dane tylko z klawiatury. Zrewidujemy t decyzj w rozdziale 7. Dlaczego zastosowalimy dugaw nazw putback() zamiast krótszej put()? Chcielimy podkreli asymetri midzy funkcjami get() i putback() — to jest strumie wejciowy, a nie co, co mona wykorzysta take do ogólnych celów zwizanych z wysyaniem danych na wyjcie. Poza tym w bibliotece istream take znajduje si funkcja putback(), a spójno nazw jest jedn z podanych cech kadego systemu. Dziki temu atwiej jest zapamitywa te nazwy i unika bdów. Po tym wstpie moemy ju utworzy typ Token_stream i uy go: Token_stream ts; // Obiekt typu Token_stream o nazwie ts. Token t = ts.get(); // Daje nastpny token ze strumienia ts. // … ts.putback(t); // Wkada token t z powrotem do strumienia ts. Mamy ju wszystko, czego potrzebujemy do napisania pozostaej czci kalkulatora. 6.8.1. Implementacja typu Token_stream Zaimplementujemy trzy wymienione funkcje strumienia Token_stream. Jak bdzie si ten strumie prezentowa? Tzn., jakie dane musz by w nim przechowywane, aby spenia swoje zadanie? Potrzebujemy miejsca do przechowywania tokenów, które woymy do niego. Dla uproszczenia zaómy, e mona w nim przechowywa tylko jeden token na raz. Na potrzeby naszego programu to wystarczy (i na potrzeby wielu innych te). W zwizku z tym potrzebujemy
208 ROZDZIA 6 • PISANIE PROGRAMU miejsca do przechowania jednego tokenu i wskanika oznaczajcego, czy to miejsce jest wolne czy zajte: class Token_stream { public: Token_stream(); // Tworzy obiekt typu Token_stream, który wczytuje dane ze strumienia cin. Token get(); // Daje token (funkcja get() zostaa zdefiniowana w innym miejscu). void putback(Token t); // Wkada token z powrotem. private: bool full; // Informuje, czy w buforze jest token. Token buffer; // Miejsce do przechowywania tokenu zapisanego w strumieniu za pomoc funkcji //putback(). }; Teraz moemy zdefiniowa (napisa) nasze trzy funkcje skadowe. Konstruktor i funkcja putback() bd atwe, poniewa maj mao do zrobienia. Dlatego zajmiemy si nimi na pocztku. Konstruktor ustawia tylko zmienn full na warto oznaczajc, e bufor jest pusty: Token_stream::Token_stream() :full(false), buffer(0) // Bufor jest pusty. { } Jeli definicja skadowej znajduje si poza definicj klasy, naley wskaza, do której klasy ma nalee. Suy do tego nastpujca notacja: nazwa_klasy::nazwa_skadowej Tutaj definiujemy konstruktor klasy Token_stream. Konstruktor to funkcja skadowa o takiej samej nazwie, jak klasa, do której naley. Po co definiowa skadow poza klas? Przede wszystkim dla zachowania przejrzystoci — w definicji klasy mona znale gównie informacje o tym, co klasa potrafi „robi”. Definicje funkcji skadowych to implementacje okrelajce sposób, w jaki s robione róne rzeczy. Wolimy umieci je gdzie indziej, aby nie przeszkadzay. Ideaem, do którego dymy, jest, aby kada jednostka logiczna programu miecia si w caoci na ekranie. Definicje klas zazwyczaj speniaj ten wymóg, ale tylko jeli definicje ich funkcji skadowych przeniesie si gdzie indziej, poza klas. Skadowe klasy inicjuje si w licie inicjatorów skadowych (podrozdzia 6.3.3). Instrukcja full(false) ustawia skadow full na false, a buffer(0) inicjuje skadow buffer „udawanym tokenem”, który wymylilimy na poczekaniu. Z definicji typu Token (podrozdzia 6.3.3) wynika, e kady token musi zosta zainicjowany, dlatego nie moglimy zignorowa Token_stream::buffer. Funkcja skadowa putback() zapisuje swój argument w buforze strumienia Token_stream: void Token_stream::putback(Token t) { buffer = t; // Kopiuje t do bufora. full = true; // Bufor jest peny. }
- Page 1 and 2: Programowanie. Teoria i praktyka z
- Page 3 and 4: 4 SPIS TRECI Rozdzia 1. Komputery,
- Page 5 and 6: 6 SPIS TRECI Rozdzia 6. Pisanie pro
- Page 7 and 8: 8 SPIS TRECI Cz II Wejcie i wyjcie
- Page 9 and 10: 10 SPIS TRECI 14.2. Klasa Shape 448
- Page 11 and 12: 12 SPIS TRECI 18.5.3. Inicjowanie t
- Page 13 and 14: 14 SPIS TRECI 22.2. Krótka histori
- Page 15 and 16: 16 SPIS TRECI 26.3.3. Algorytmy i n
- Page 17 and 18: 18 SPIS TRECI Dodatek D Instalowani
- Page 19 and 20: 176 ROZDZIA 6 • PISANIE PROGRAMU
- Page 21 and 22: 178 ROZDZIA 6 • PISANIE PROGRAMU
- Page 23 and 24: 180 ROZDZIA 6 • PISANIE PROGRAMU
- Page 25 and 26: 182 ROZDZIA 6 • PISANIE PROGRAMU
- Page 27 and 28: 184 ROZDZIA 6 • PISANIE PROGRAMU
- Page 29 and 30: 186 ROZDZIA 6 • PISANIE PROGRAMU
- Page 31 and 32: 188 ROZDZIA 6 • PISANIE PROGRAMU
- Page 33 and 34: 190 ROZDZIA 6 • PISANIE PROGRAMU
- Page 35 and 36: 192 ROZDZIA 6 • PISANIE PROGRAMU
- Page 37 and 38: 194 ROZDZIA 6 • PISANIE PROGRAMU
- Page 39 and 40: 196 ROZDZIA 6 • PISANIE PROGRAMU
- Page 41 and 42: 198 ROZDZIA 6 • PISANIE PROGRAMU
- Page 43 and 44: 200 ROZDZIA 6 • PISANIE PROGRAMU
- Page 45 and 46: 202 ROZDZIA 6 • PISANIE PROGRAMU
- Page 47 and 48: 204 ROZDZIA 6 • PISANIE PROGRAMU
- Page 49: 206 ROZDZIA 6 • PISANIE PROGRAMU
- Page 53 and 54: 210 ROZDZIA 6 • PISANIE PROGRAMU
- Page 55 and 56: w i c z e n i a 212 ROZDZIA 6 • P
- Page 57 and 58: 214 ROZDZIA 6 • PISANIE PROGRAMU
208 ROZDZIA 6 • PISANIE PROGRAMU<br />
miejsca do przechowania jednego tokenu i wskanika oznaczajcego, czy to miejsce jest wolne<br />
czy zajte:<br />
class Token_stream {<br />
public:<br />
Token_stream(); // Tworzy obiekt typu Token_stream, który wczytuje dane ze strumienia<br />
cin.<br />
Token get();<br />
// Daje token (funkcja get() zostaa zdefiniowana w innym miejscu).<br />
void putback(Token t); // Wkada token z powrotem.<br />
private:<br />
bool full; // Informuje, czy w buforze jest token.<br />
Token buffer; // Miejsce do przechowywania tokenu zapisanego w strumieniu za pomoc funkcji<br />
//putback().<br />
};<br />
Teraz moemy zdefiniowa (napisa) nasze trzy funkcje skadowe. Konstruktor i funkcja<br />
putback() bd atwe, poniewa maj mao do zrobienia. Dlatego zajmiemy si nimi na pocztku.<br />
Konstruktor ustawia tylko zmienn full na warto oznaczajc, e bufor jest pusty:<br />
Token_stream::Token_stream()<br />
:full(false), buffer(0) // Bufor jest pusty.<br />
{<br />
}<br />
Jeli definicja skadowej znajduje si poza definicj klasy, naley wskaza, do której klasy ma<br />
nalee. Suy do tego nastpujca notacja:<br />
nazwa_klasy::nazwa_skadowej<br />
Tutaj definiujemy konstruktor klasy Token_stream. Konstruktor to funkcja skadowa o takiej<br />
samej nazwie, jak klasa, do której naley.<br />
Po co definiowa skadow poza klas? Przede wszystkim dla zachowania przejrzystoci<br />
— w definicji klasy mona znale gównie informacje o tym, co klasa potrafi „robi”. Definicje<br />
funkcji skadowych to implementacje okrelajce sposób, w jaki s robione róne rzeczy.<br />
Wolimy umieci je gdzie indziej, aby nie przeszkadzay. Ideaem, do którego dymy, jest,<br />
aby kada jednostka logiczna programu miecia si w caoci na ekranie. Definicje klas zazwyczaj<br />
speniaj ten wymóg, ale tylko jeli definicje ich funkcji skadowych przeniesie si gdzie<br />
indziej, poza klas.<br />
Skadowe klasy inicjuje si w licie inicjatorów skadowych (podrozdzia 6.3.3). Instrukcja<br />
full(false) ustawia skadow full na false, a buffer(0) inicjuje skadow buffer „udawanym<br />
tokenem”, który wymylilimy na poczekaniu. Z definicji typu Token (podrozdzia 6.3.3) wynika, e<br />
kady token musi zosta zainicjowany, dlatego nie moglimy zignorowa Token_stream::buffer.<br />
Funkcja skadowa putback() zapisuje swój argument w buforze strumienia Token_stream:<br />
void Token_stream::putback(Token t)<br />
{<br />
buffer = t; // Kopiuje t do bufora.<br />
full = true; // Bufor jest peny.<br />
}