Sunteți pe pagina 1din 60

Plan

• Derivare şi parametrizare
• Polimorfism
– suprascriere -> legare statică
• exemplu
– funcţii virtuale -> legare dinamică
• exemplu
• static_cast, dinamic_cast
• Operatorul typeid
• Ierarhia de clase ios
• Fișiere C++

POO(C++) 2005-2006 Gh GRIGORAS 1


Derivare - parametrizare

• Se poate defini o clasă parametrizată prin


derivare
– de la o clasă parametrizată
– de la o instanţă a unei clase parametrizate
– de la o clasă obişnuită

• Se poate defini o clasă obişnuită prin


derivare de la o instanţă a unei clase
parametrizate

POO(C++) 2005-2006 Gh GRIGORAS 2


Derivare - parametrizare
template <class T>
class Fisier: protected fstream {};

template <class T>


class FisierCitire: public virtual Fisier<T> {};

template <class T>


class FisierScriere: public virtual Fisier<T> {};

template <class T>


class FisierCitireScriere: public FisierCitire<T>,
public FisierScriere<T>
{};

POO(C++) 2005-2006 Gh GRIGORAS 3


Derivare şi parametrizare - Exemplu
template <class TYPE>
class stack {
public:
explicit stack(int size = 100) // doar explicit
: max_len(size), top(EMPTY)
{s = new TYPE[size]; assert (s != 0);}
~stack() { delete []s; }
void reset() { top = EMPTY; }
void push(TYPE c) { s[++top] = c; }
TYPE pop() { return s[top--]; }
TYPE top_of()const { return s[top]; }
bool empty()const { return top == EMPTY;}
bool full()const { return top == max_len - 1;}
private:
enum { EMPTY = -1 };
TYPE* s;
int max_len;
int top;
};

POO(C++) 2005-2006 Gh GRIGORAS 4


Derivare şi parametrizare - Exemplu
class safe_char_stack : public stack<char> {
public:
// push, pop sigure
void push(char c)
{ assert (!full()); stack<char>::push(c); }
char pop()
{assert (!empty()); return (stack<char>::pop());}
};

template <class Type>


class safe_stack : public stack<Type> {
public:
// push, pop sigure
void push(Type c)
{ assert (!full()); stack<Type>::push(c); }
char pop()
{assert (!empty()); return (stack<Type>::pop());}
};

POO(C++) 2005-2006 Gh GRIGORAS 5


Polimorfism - suprascriere
• Legare statică: asocierea apel funcţie --
corp(implementare) funcţie se face înainte de execuţia
programului (early binding) – la compilare

POO(C++) 2005-2006 Gh GRIGORAS 6


Polimorfism - suprascriere
• persoanele, studenţii, profesorii au abilitatea de a semna:
class Persoana {
public:
//…
string getNume() const;
void semneaza();
protected:
string id;
string nume;
};
class Student:public Persoana {
//…
void semneaza();
}
class Profesor:public Persoana {
//…
void semneaza();
}

POO(C++) 2005-2006 Gh GRIGORAS 7


Polimorfism - suprascriere
• fiecare semnează in felul său:
void Persoana::semneaza()
{
cout << getNume() << endl;
}
void Student::semneaza()
{
cout << "Student " << getNume() << endl;
}
void Profesor::semneaza()
{
cout << "Profesor " << getNume() << endl;
}

POO(C++) 2005-2006 Gh GRIGORAS 8


Polimorfism - suprascriere
• Exemplu:
Persoana pers("1001","Popescu Ion");
Student stud("1002", "Angelescu Sorin");
Profesor prof("1003","Marinescu Pavel");
pers.semneaza();
stud.semneaza();
prof.semneaza();

Popescu Ion
Student Angelescu Sorin
Profesor Marinescu Pavel

POO(C++) 2005-2006 Gh GRIGORAS 9


Polimorfism - suprascriere
• Exemplu:

// studentul poate semna ca persoana


stud.Persoana::semneaza();

// ... si profesorul poate semna ca persoana


prof.Persoana::semneaza();

Angelescu Sorin
Marinescu Pavel

POO(C++) 2005-2006 Gh GRIGORAS 10


Polimorfism - suprascriere
• Suprascriere -> legare statică ( asocierea apel
funcţie – implementare se face la compilare):
void semneaza(Persoana& p)
{
p.semneaza();
};
semneaza(pers);
semneaza(stud);// &stud poate inlocui &p
semneaza(prof);// &prof poate inlocui &p

Popescu Ion
Angelescu Sorin
Marinescu Pavel

POO(C++) 2005-2006 Gh GRIGORAS 11


Polimorfism - Funcţii virtuale

• Legare dinamică: asocierea apel funcţie --


corp(implementare) funcţie se face la
execuţia programului (late binding, run-
time binding), pe baza tipului obiectului
căruia i se transmite funcţia ca mesaj. În
acest caz, funcţia se zice polimorfă

POO(C++) 2005-2006 Gh GRIGORAS 12


Implementare polimorfism în C++:
• Declaraţia funcţiei în clasa de bază precedată de
cuvântul virtual
class Persoana {
public:
//…
virtual void semneaza();
//…
};
• O funcţie virtuală pentru clasa de bază rămâne
virtuală pentru clasele derivate. La redefinirea
unei funcţii virtuale în clasa derivată (overriding)
nu e nevoie din nou de specificarea virtual

POO(C++) 2005-2006 Gh GRIGORAS 13


Polimorfism – funcţii virtuale
• Polimorfism funcţii virtuale-> legare dinamică:
Persoana pers("1001","Popescu Ion");
Student stud("1002", "Angelescu Sorin");
Profesor prof("1003","Marinescu Pavel");
pers.semneaza();
stud.semneaza();
prof.semneaza();
semneaza(pers);
semneaza(stud);
semneaza(prof);

Popescu Ion
Student Angelescu Sorin
Profesor Marinescu Pavel
Popescu Ion
Student Angelescu Sorin
Profesor Marinescu Pavel

POO(C++) 2005-2006 Gh GRIGORAS 14


Implementare polimorfism în C++:
• Compilatorul creează o tabelă - VTABLE - pentru
fiecare clasă care conţine funcţii virtuale; adresele
tuturor funcţiilor virtuale sunt plasate în această
tabelă. Sistemul creează un pointer VPTR în
fiecare clasă cu funcţii virtuale; el pointează la
această tabelă şi alege funcţia corectă la un apel
polimorfic

std::cout << sizeof(pers);

• Se obţine:
– 32 dacă semneaza() nu este virtuală
– 36 dacă semneaza() este virtuală

POO(C++) 2005-2006 Gh GRIGORAS 15


Implementare polimorfism în C++:

POO(C++) 2005-2006 Gh GRIGORAS 16


Implementare polimorfism în C++:

• Un constructor nu poate fi virtual

• Un destructor poate fi virtual; destructorii


claselor derivate ar trebui să fie virtuali;
asta asigură apelul lor la distrugerea cu
delete a pointerilor la clasa de bază

POO(C++) 2005-2006 Gh GRIGORAS 17


Destructor virtual
class A{ void f(){
public: A* pA;
A(){p = new char[5];} pA = new D();
~A(){delete [] p;} //…
protected: delete pA;// doar apel ~A()
char* p; }
}; void main(){
class D:public A{ for(int i = 0; i<9; i++)
public: f();
D(){q = new char[500];} }
~D(){delete [] q;}
protected // pentru a se apela si ~D()
char* q; // se declara virtual ~A(){…}
};

POO(C++) 2005-2006 Gh GRIGORAS 18


Clase abstracte
• Reprezentarea unor concepte abstracte: figură (geometrică),
formă, etc.
class Shape{
public:
virtual void rotate(int) {error(“Shape::rotate”);}
virtual void draw() {error(“Shape::drow”);}
// …
};
• Nu pot fi instanţiate astfel de clase; nu pot exista obiecte
abstracte
• Alternativa: declararea funcţiilor virtuale ca funcţii virtuale
pure:
class Shape{
public:
virtual void rotate(int) = 0;
virtual void draw() = 0;
// …
};

• O clasă abstractă este o interfaţă


POO(C++) 2005-2006 Gh GRIGORAS 19
Clase de bază abstracte
• Clasă de bază abstractă: o clasă ce are cel
puţin o funcţie virtuală pură ( = 0):
class ABC{
public:
virtual void m1() = 0;
//
};

• Iniţializarea unei metode virtuale cu zero


este o convenţie sintactică: specificarea
unei clasei abstracte ce nu poate fi
instanţiată
POO(C++) 2005-2006 Gh GRIGORAS 20
Clase de bază abstracte
• Clasele derivate din clase abstracte trebuie să
definească toate metodele virtuale pure - override
- altfel devin ele însele abstracte

• O clasă abstractă poate să aibă şi alţi membri (ce


se moştenesc)

• Numai o metodă virtuală poate fi pură

• O clasă abstractă poate fi folosită în sisteme mari


pentru a specifica cerinţele de proiectare.
POO(C++) 2005-2006 Gh GRIGORAS 21
Clase de bază abstracte - Exemplu
class figura{
public:
virtual void read_figure ()=0;
virtual void compute_area ();
virtual void compute_perim ();
virtual void display_fig ();
protected:
double area;
double perimeter;
};
class cerc : public figura //cercul este o figura
{
public:
void read_figure ();
void compute_area ();
void compute_perim ();
void display_fig ();
private:
double radius;
};

POO(C++) 2005-2006 Gh GRIGORAS 22


Clase de bază abstracte - Exemplu
// FILE: figura.cpp
#include “figura.h"
//…
void figura::compute_perim()
{perimeter = 0.0;}

void figura::compute_area()
{area = 0.0;}

void figura::display_fig (){


cout << "Aria este " << area << endl;
cout << "Perimetrul este " << perimeter << endl;
}

POO(C++) 2005-2006 Gh GRIGORAS 23


Clase de bază abstracte - Exemplu
// FILE: cerc.cpp
// IMPLEMENTAREA CLASEI cerc
#include "cerc.h“
//…
const double pi = 3.1415927;
void cerc::read_figure (){
cout << “Raza > ";
cin >> radius;
}
void cerc::compute_perim (){
perimeter= 2.0 * pi * radius;
}
void cerc::compute_area (){
area = pi * radius * radius;
}
void cerc::display_fig (){
cout << "Figura este cerc" << endl;
cout << "Raza cercului este" << radius << endl;
figura::display_fig ();
}
POO(C++) 2005-2006 Gh GRIGORAS 24
Clase de bază abstracte - Exemplu
void main(){
figura* get_figure ();//Alegerea unei figuri

void process_figure(figura&);
figura* my_fig; // pointer la o figura

// Se proceseaza figurile alese


for (my_fig = get_figure (); my_fig != 0; my_fig =
get_figure ()) {
process_figure (*my_fig);
delete my_fig; // se elibereaza memoria
}
}
// PROCESAREA UNEI FIGURI
void process_figure(figura& fig){
fig.read_figure ();
fig.compute_area ();
fig.compute_perim ();
fig.display_fig ();
}
POO(C++) 2005-2006 Gh GRIGORAS 25
Type Casting
• Conversia unei expresii de tip dat într-un alt tip
– Conversie implicită: existenţa unui constructor de conversie
class A {}; class B { public: B (A a) {} }; A a; B b=a;
– Conversie explicită
b = (int) a;
CDummy d; CAddition * padd;
padd = (CAddition*) &d;
• Conversia explicită permite conversia de la un pointer al unei clase la un
pointer al altei clase(chiar fără legătură între ele) dar utilizarea sub această
formă poate conduce la erori la execuţie sau la rezultate imprevizibile
• Pentru controlul acestor conversii între clase s-au introdus operatorii:
– dynamic_cast <new_type> (expression)
– reinterpret_cast <new_type> (expression)
– static_cast <new_type> (expression)
– const_cast <new_type> (expression)

POO(C++) 2005-2006 Gh GRIGORAS 26


dynamic_cast
• Se poate folosi doar cu pointeri și referinţe
• Asigură faptul că rezultatul conversiei este un obiect
valid, complet, al clasei cerute
– Este ok conversia de la pointer al clasei derivate la
pointer al clasei de bază
– Conversia de la pointer al clasei de bază la pointer al
clasei derivate este permisă doar în prezenţa
polimorfismului
class CBase { };
class CDerived: public CBase { };
CBase b; CBase* pb;
CDerived d; CDerived* pd;
pb = dynamic_cast<CBase*>(&d);
// ok: derived-to-base
pd = dynamic_cast<CDerived*>(&b);
// wrong: base-to-derived

POO(C++) 2005-2006 Gh GRIGORAS 27


dynamic_cast
• În cazul polimorfismului dynamic_cast produce o verificare la
momentul execuţiei pentru a se asigura că expresia conduce la
un obiect valid; altfel se returnează pointerul nul
class CBase { virtual void dummy() {} };
class CDerived: public CBase { int a; };

int main () {
try {
CBase * pba = new CDerived;
CBase * pbb = new CBase;
CDerived * pd;

pd = dynamic_cast<CDerived*>(pba);
if (pd==0) cout << "Null pointer on first type-cast" << endl;

pd = dynamic_cast<CDerived*>(pbb);
if (pd==0) cout << "Null pointer on second type-cast" << endl;

} catch (exception& e) {cout << "Exception: " << e.what();}


return 0;
}

POO(C++) 2005-2006 Gh GRIGORAS 28


dynamic_cast
• Deosebirea între pointerii(la clasa de bază) pba și pbb

• Dacă nu se poate face conversia, se returnează


pointerul nul
(cazul pd = dynamic_cast<CDerived*>(pbb);)

• Dacă dynamic_cast este folosit pentru conversia la


un tip referinţă și conversia nu este posibilă, este
aruncată o excepţie de tip bad_cast.

POO(C++) 2005-2006 Gh GRIGORAS 29


dynamic_cast
std::vector<Figura*> v[20];
//…
int nrCercuri = 0;
int nrDrept = 0;
for (i=0; i< v.size(); i++)
{
if (dynamic_cast<Cerc*>(v[i])){
v[i]->arie();
nrCercuri++;
}
if (dynamic_cast<Dreptunghi*>(v[i])){
v[i]->arie();
nrDrept++;
}
}

POO(C++) 2005-2006 Gh GRIGORAS 30


static_cast
• static_cast poate face conversii între pointeri dar
nu se face verificarea dacă conversia este corectă,
programatorul trebuie să se asigure de acest lucru, altfel
rezultatele pot fi imprevizibile (dacă nu se obţin erori la
dereferenţierea pointerilor rezultaţi)

class CBase {};


class CDerived: public CBase {};
CBase *a = new CBase;
CDerived *b = static_cast<CDerived*>(a);

• static_cast poate fi folosit pentru orice alt fel de conversie


inclusiv pentru tipurile fundamentale:
double d=3.14159265;
int i = static_cast<int>(d);
POO(C++) 2005-2006 Gh GRIGORAS 31
reinterpret_cast
• reinterpret_cast convertește un pointer la
un tip la un pointer la alt tip chiar dacă clasele
sunt incompatibile. Conversia se face prin simpla
copiere a valorii binare; nu se face nici o verificare
asupra conţinutului pointat

• Se poate face și conversie de la pointer (la un tip)


la tipul întreg, cu singura garanţie că acesta, dacă
a fost memorat în întregime, poate fi reconvertit
la pointer

POO(C++) 2005-2006 Gh GRIGORAS 32


const_cast
• Este legat de atributul const al obiectelor; poate fi folosit
pentru a transmite un argument const la o funcţie ce nu are
parametru const:

// const_cast
#include <iostream>
using namespace std;

void print (char * str)


{
cout << str << endl;
}

int main () {
const char * c = “exemplu ";
print ( const_cast<char *> (c) );
return 0;
}

POO(C++) 2005-2006 Gh GRIGORAS 33


Operatorul typeid
• Operatorul typeid permite determinarea tipului unui obiect
la momentul execuţiei

• Syntaxa
typeid( type-id )
typeid( expresie )

• Rezultatul este referinţă la un obiect al clasei type_info


(fişierul <typeinfo> )
• Dacă se aplică la un type-id atunci returnează o referinţă la
type_info ce reprezintă numele tipului(type-id)
• Dacă se aplică la o expresie atunci rezultatul este referinţă la
type_info ce reprezintă tipul obiectului denotat de
expresie

POO(C++) 2005-2006 Gh GRIGORAS 34


Operatorul typeid
• Clasa type_info descrie informaţii relative
la tip; acestea sunt generate de compilator.
Obiectele clasei conţin un pointer la char -
numele tipului:
class type_info {
public:
virtual ~type_info();
int operator==(const type_info& rhs) const;
int operator!=(const type_info& rhs) const;
const char* name() const;
//..
private:
//...
};

POO(C++) 2005-2006 Gh GRIGORAS 35


Exemplu
// typeid
#include <iostream>
#include <typeinfo>
using namespace std;

int main () {
int *a,b;
a=0; b=0;
if (typeid(a) != typeid(b))
{
cout << "a and b are of different types:\n";
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
}
return 0;
}

POO(C++) 2005-2006 Gh GRIGORAS 36


// typeid, polymorphic class
#include <iostream>
#include <typeinfo>
#include <exception>
using namespace std;

class CBase { virtual void f(){} };


class CDerived : public CBase {};

int main () {
try {
CBase* a = new CBase;
CBase* b = new CDerived;
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
cout << "*a is: " << typeid(*a).name() << '\n';
cout << "*b is: " << typeid(*b).name() << '\n';
} catch (exception& e) { cout << "Exception: " <<
e.what() << endl; }
return 0;
}

POO(C++) 2005-2006 Gh GRIGORAS 37


Operatorul typeid
#include <typeinfo>
// utilizarea metodei type_info::typeid()
//si static_cast<T>(exp) in loc de virtual

double f(RxR *pa)


{
if (typeid(*pa) == typeid(RxR))
return static_cast<RxR *>(pa)->modul();
if (typeid(*pa) == typeid(RxRxR))
return static_cast<RxRxR *>(pa)->modul();
return 0.0;
}

POO(C++) 2005-2006 Gh GRIGORAS 38


Ierarhia de clase iostream
ios_base
Mostenire virtuala

ios<>

istream<>
ostream<>

istringstream<> ostringstream<>

ifstream<> iostream<> ofstream<>

fstream<> stringstream<>

POO(C++) 2005-2006 Gh GRIGORAS 39


Ierarhia de clase iostream
• Clasele cu sufixul <> sunt template - uri parametrizate cu un tip
caracter iar numele lor au prefixul basic_ :

template <class E, class T = char_traits<E> >


class basic_ios : public ios_base {
//…
};
• char_traits<E> conţine informaţii pentru
manipularea elementelor de tip E

template <class E, class T = char_traits<E> >


class basic_istream : virtual public basic_ios<E, T>
{
//…
};
POO(C++) 2005-2006 Gh GRIGORAS 40
Ierarhia de clase streambuf

streambuf<>

filebuf<> stringbuf<>

POO(C++) 2005-2006 Gh GRIGORAS 41


Clasa basic_iostream

template <class E, class T = char_traits<E>>


class basic_iostream :
public basic_istream<E, T>,
public basic_ostream<E, T> {
public:
explicit basic_iostream(basic_streambuf<E, T>* sb);
virtual ~basic_iostream();
};

POO(C++) 2005-2006 Gh GRIGORAS 42


Fisierul header <iosfwd>

typedef basic_ios<char, char_traits<char> > ios;


typedef basic_istream<char, char_traits<char> > istream;
typedef basic_ostream<char, char_traits<char> > ostream;

typedef basic_iostream<char, char_traits<char> > iostream;


typedef basic_ifstream<char, char_traits<char> > ifstream;
typedef basic_ofstream<char, char_traits<char> > ofstream;
typedef basic_fstream<char, char_traits<char> > fstream;

POO(C++) 2005-2006 Gh GRIGORAS 43


Clasa ostream
• Un obiect din ostream (flux de ieșire) este un
mecanism pentru conversia valorilor de diverse
tipuri în secvenţe de caractere
• În <iostream>:
ostream cout; //fluxul standard de iesire
ostream cerr; // mesaje eroare,fara buffer
ostream clog; // mesaje eroare,cu buffer

POO(C++) 2005-2006 Gh GRIGORAS 44


operator<< (în ostream)
basic_ostream& operator<< (const char *s);
basic_ostream& operator<< (char c);
basic_ostream& operator<< (bool n);
basic_ostream& operator<< (short n);
basic_ostream& operator<< (unsigned short n);
basic_ostream& operator<< (int n);
basic_ostream& operator<< (unsigned int n);
basic_ostream& operator<< (long n);
basic_ostream& operator<< (unsigned long n);
basic_ostream& operator<< (float n);
basic_ostream& operator<< (double n);
basic_ostream& operator<< (long double n);
basic_ostream& operator<< (void * n);
basic_ostream& put(E c); // scrie c
basic_ostream& write(E *p, streamsize n); // scrie p[0],…,p[n-1]
basic_ostream& flush(); // goleste bufferul
pos_type tellp(); // pozitia curenta
basic_ostream& seekp(pos_type pos); // noua positie pos
basic_ostream& seekp(off_type off, ios_base::seek_dir way);
// pozitia way (= beg, cur, end) + off

POO(C++) 2005-2006 Gh GRIGORAS 45


Formatare, fișierul <iomanip>
void main()
{
int i = 10, j = 16, k = 24;
cout << i << '\t' << j << '\t' << k << endl;
cout << oct << i << '\t' << j << '\t' << k << endl;
cout << hex << i << '\t' << j << '\t' << k << endl;
cout << "Introdu 3 intregi: " << endl;
cin >> i >> hex >> j >> k;
cout << dec << i << '\t' << j << '\t' << k << endl;
}

/*
10 16 24
12 20 30
a 10 18
Introdu 3 intregi:
42 11 12a
42 17 298
*/

POO(C++) 2005-2006 Gh GRIGORAS 46


Manipulatori
MANIPULATOR EFECTUL FISIERUL

endl Scrie newline iostream


ends Scrie NULL in string iostream
flush Goleste iostream
dec Baza 10 iostream
hex Baza 16 iostream
oct Baza 8 iostream
ws Ignoră spaţiile la intrare iostream
skipws Ignoră spaţiile iostream
noskipws Nu ignoră spaţiile iostream
showpoint Se scrie punctul zecimal şi zerourile iostream
noshowpoint Nu se scriu zerourile, nici punctul iostream
showpos Scrie + la numerele nenegative iostream
noshowpos Nu scrie + la numerele nenegative iostream
boolalpha Scrie true si false pentru bool iostream
noboolalpha Scrie 1 si 0 pentru bool iostream

POO(C++) 2005-2006 Gh GRIGORAS 47


Manipulatori
MANIPULATOR EFECTUL FISIERUL

scientific Notaţia ştiinţifică pentru numere reale iostream

fixed Notaţia punct fix pentru numere reale iostream

left Aliniere stânga iostream

right Aliniere dreapta iostream

internal Caract. de umplere intre semn si valoare iostream

setw(int) Seteaza dimensiunea câmpului iomanip

setfill(char c) Caracterul c înlocueşte blancurile iomanip

setbase(int) Setarea bazei iomanip

setprecision(int) Seteaza precizia in flotant iomanip

setiosflags(long) Seteaza bitii pentru format iomanip

resetiosflags(long) Reseteaza bitii pentru format iomanip

POO(C++) 2005-2006 Gh GRIGORAS 48


double a = 12.05, b = 11.25, c = -200.89;
cout << a << ',' << b << ',' << c << endl;
cout << setfill('*') << setprecision(3);
cout << setw(10) << a << endl;
cout << setw(10) << b << endl;
cout << setw(10) << c << endl;
cout << setw(10) << showpoint << c << endl;
cout << setfill(' ') << right << showpoint;
cout << setw(15) << setprecision(5)
<< c << endl;
cout << scientific << c << endl;
char d;
cin >> noskipws;
while(cin >>d)
cout << d;
12.05,11.25,-200.89
******12.1
******11.3
******-201
*****-201.
-200.89
-2.00890e+002
text pentru test
text pentru test
POO(C++) 2005-2006 Gh GRIGORAS 49
Clasa istream

• Un obiect din istream (flux de intrare) este un


mecanism pentru conversia caracterelor în valori de
diverse tipuri
• În <iostream>:
istream cin; //fluxul standard de intrare

• În basic_istream este definit operator>>


pentru tipurile fundamentale

POO(C++) 2005-2006 Gh GRIGORAS 50


Funcţii utile în istream
streamsize gcount() const;
int_type get();
basic_istream& get(E& c);
basic_istream& get(E *s, streamsize n);
basic_istream& get(E *s, streamsize n, E delim);
basic_istream& get(basic_streambuf<E, T> *sb);
basic_istream& get(basic_streambuf<E, T> *sb, E delim);
basic_istream& getline(E *s, streamsize n);
basic_istream& getline(E *s, streamsize n, E delim);
basic_istream& ignore(streamsize n = 1,
int_type delim = T::eof());
int_type peek(); // citeste fara a-l extrage
basic_istream& read(E *s, streamsize n);
streamsize readsome(E *s, streamsize n); // peek cel mult n
basic_istream& putback(E c); // pune c in buferul de intrare
basic_istream& unget(); // pune inapoi ultimul citit
pos_type tellg();
basic_istream& seekg(pos_type pos);
basic_istream& seekg(off_type off, ios_base::seek_dir way);
int sync(); // flush input

POO(C++) 2005-2006 Gh GRIGORAS 51


Fișiere
• Într-un program C++ fluxurile standard cin,
cout, cerr, clog sunt disponibile;
corespondenţa lor cu dispozitivele (fișierele )
standard este facută de sistem

• Programatorul poate crea fluxuri proprii –


obiecte ale clasei fstream (ifstream,
ofstream). Atașarea fluxului unui fișier sau
unui string se face de programator:
– la declarare cu un constructor cu parametri
– după declarare prin mesajul open()
POO(C++) 2005-2006 Gh GRIGORAS 52
Fișiere
• Constructorii clasei fstream:
explicit basic_fstream();
explicit basic_fstream(const char *s,
ios_base::openmode mode =
ios_base::in | ios_base::out);
• Metode:
bool is_open() const;
void open(const char *s,
ios_base::openmode mode =
ios_base::in | ios_base::out);
void close();

POO(C++) 2005-2006 Gh GRIGORAS 53


Fișiere de intrare

• Constructorii clasei ifstream:


explicit basic_ifstream();
explicit basic_ifstream(const char *s,
ios_base::openmode mode = ios_base::in);

• Metode:
bool is_open() const;
void open(const char *s,
ios_base::openmode mode = ios_base::in);
void close();

POO(C++) 2005-2006 Gh GRIGORAS 54


#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main () {
string line;
ifstream myfile ("file.cpp");
if (myfile.is_open())
{
while (! myfile.eof() )
{
getline (myfile,line);
cout << line << endl;
}
myfile.close();
}else
cout << "Unable to open file";

return 0;
}

POO(C++) 2005-2006 Gh GRIGORAS 55


Fișiere de ieșire
• Constructorii clasei ofstream:
explicit basic_ofstream();
explicit basic_ofstream(const char *s,
ios_base::openmode which =
ios_base::out | ios_base::trunc);
• Metode:
bool is_open() const;
void open(const char *s,
ios_base::openmode mode =
ios_base::out | ios_base::trunc);
void close();

POO(C++) 2005-2006 Gh GRIGORAS 56


#include <iostream>
#include <fstream>
using namespace std;

int main () {
ofstream myfile ("example.txt");
if (myfile.is_open()){
myfile << "This is a line.\n";
myfile << "This is another line.\n";
myfile.close();
}
else
cout << "Unable to open file";
return 0;
}

POO(C++) 2005-2006 Gh GRIGORAS 57


ios_base::openmode

• app, poziţionare la sfârșit înainte de fiecare


inserţie
• ate, poziţionare la sfârșit la deschiderea
fișierului
• binary, citirea fișierului în mod binar și nu în
mod text
• in, permite extragerea (fișier de intrare)
• out, permite inserţia (fișier de ieșire)
• trunc, trunchiază un fișier existent la prima
creare a fluxului ce-l controlează
POO(C++) 2005-2006 Gh GRIGORAS 58
Clasa stringstream
• Permite ca stringurile să fie tratate ca fișiere:

explicit basic_stringstream(ios_base::openmode mode


= ios_base::in | ios_base::out);

explicit basic_stringstream(const
basic_string<E,T,A>& x, ios_base::openmode mode =
ios_base::in | ios_base::out);

POO(C++) 2005-2006 Gh GRIGORAS 59


#include <iostream>
#include <sstream>
using namespace std;

int main()
{
stringstream s("This is initial string.");

// get string
string str = s.str();
cout << str << endl;

// output to string stream


s << "Numbers: " << 10 << " " << 123.2;

int i;
double d;
s >> str >> i >> d;
cout << str << " " << i << " " << d;

return 0;
}

POO(C++) 2005-2006 Gh GRIGORAS 60

S-ar putea să vă placă și