C++ păstrează sistemul de intrare/ieșire din C, dar adaugă unul propriu, construit pe principiile programării orientate pe obiecte: mai sigur, mai flexibil și extensibil la tipuri definite de utilizator. Această ultimă lucrare face și trecerea de la structuri la clase.
1Obiectivele lucrării
- Utilizarea streamurilor
cin,cout,cerrșiclog - Formatarea ieșirii cu manipulatori
- Lucrul cu fișiere prin
ifstreamșiofstream - Definirea unei clase cu date membre și funcții membre
- Scrierea constructorilor și a destructorului
- Aplicarea principiului încapsulării
2Ierarhia de clase I/O
Operațiile de intrare/ieșire se realizează cu ajutorul a două ierarhii de clase, declarate în
fișierele iostream.h și fstream.h:
3Streamurile predefinite
| Stream | Semnificație | Echipament implicit | Echivalent în C |
|---|---|---|---|
cin | intrare standard | tastatură | stdin |
cout | ieșire standard | ecran | stdout |
cerr | ieșire standard pentru erori | ecran | stderr |
clog | ieșire pentru erori, cu memorie tampon | ecran | - |
<< este operatorul de inserție (scriere),
>> cel de extracție (citire). Ambii sunt operatori supraîncărcați, ceea ce
permite înlănțuirea: cout << a << " " << b << endl;cout << obiect să funcționeze natural.4Manipulatori de format
| Manipulator | Efect | Antet necesar |
|---|---|---|
endl | linie nouă + golirea tamponului | iostream |
setw(n) | lățime minimă de n caractere | iomanip |
setprecision(n) | numărul de cifre semnificative | iomanip |
fixed | notație zecimală fixă | iostream |
scientific | notație științifică | iostream |
left / right | alinierea în câmp | iostream |
setfill(c) | caracterul de umplere | iomanip |
hex / oct / dec | baza de numerație | iostream |
boolalpha | afișează true/false în loc de 1/0 | iostream |
setw acționează doar asupra următoarei
valori afișate, apoi se resetează. Ceilalți manipulatori (fixed, setprecision,
hex) rămân activi până la o nouă schimbare.5Fișiere în C++
| Clasă | Rol | Echivalent C |
|---|---|---|
ifstream | citire din fișier | fopen(..., "r") |
ofstream | scriere în fișier | fopen(..., "w") |
fstream | citire și scriere | fopen(..., "r+") |
fclose nu mai
este posibilă - este primul beneficiu concret al abordării orientate pe obiecte.6Clase și obiecte
O clasă extinde noțiunea de structură: pe lângă date, conține și funcțiile care operează asupra lor. Un obiect este o instanță concretă a unei clase.
class NumeClasa {
private: // implicit pentru class
tip date_membre; // accesibile doar din interiorul clasei
public:
NumeClasa(); // constructor implicit
NumeClasa(parametri); // constructor cu parametri
~NumeClasa(); // destructor
tip functie_membra(...); // interfata publica
};
| Specificator | Acces din interiorul clasei | Din exterior | Din clase derivate |
|---|---|---|---|
private | da | nu | nu |
protected | da | nu | da |
public | da | da | da |
private pentru class, public pentru struct.
În rest, o structură din C++ poate avea funcții membre, constructori și destructor.Constructori și destructor
| Element | Când se apelează | Caracteristici |
|---|---|---|
| Constructor | la crearea obiectului | are numele clasei, nu returnează nimic, poate fi supraîncărcat |
| Constructor de copiere | la inițializarea dintr-un alt obiect | NumeClasa(const NumeClasa &alt) |
| Destructor | la distrugerea obiectului | ~NumeClasa(), unic, fără parametri |
7Simulator: ciclul de viață al unui obiect
Urmăriți momentele exacte în care se apelează constructorul și destructorul, inclusiv pentru obiectele create într-un bloc interior.
8Încapsularea
Datele membre se declară private, iar accesul se face exclusiv prin funcții publice.
Avantajul nu este ascunderea în sine, ci controlul: orice modificare poate fi validată.
class Temperatura {
private:
double celsius;
public:
// fara incapsulare, oricine ar putea scrie t.celsius = -500;
bool setCelsius(double v) {
if (v < -273.15) return false; // validare: zero absolut
celsius = v;
return true;
}
double getCelsius() const { return celsius; }
double getFahrenheit() const { return celsius * 9.0 / 5.0 + 32.0; }
};
const garantează
că aceasta nu modifică starea obiectului. Compilatorul verifică promisiunea și semnalează orice
încălcare - o formă simplă și eficientă de documentare executabilă.9Cod sursă
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double pi = 3.14159265358979;
cout << "Implicit: " << pi << endl;
cout << "fixed, 4 zec: " << fixed << setprecision(4) << pi << endl;
cout << "scientific: " << scientific << pi << endl;
cout << fixed << setprecision(2);
// tabel aliniat
cout << "\n" << left << setw(14) << "Produs"
<< right << setw(8) << "Buc"
<< setw(10) << "Pret" << endl;
cout << setfill('-') << setw(32) << "" << setfill(' ') << endl;
cout << left << setw(14) << "Rezistor"
<< right << setw(8) << 120 << setw(10) << 0.15 << endl;
cout << left << setw(14) << "Condensator"
<< right << setw(8) << 45 << setw(10) << 0.80 << endl;
// baze de numeratie
int v = 255;
cout << "\n" << dec << v << " = " << hex << v
<< " (hex) = " << oct << v << " (oct)" << dec << endl;
cout << boolalpha << "\n3 > 5 este " << (3 > 5) << endl;
return 0;
}
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Student {
private:
string nume;
int varsta;
double medie;
public:
// constructor implicit
Student() : nume("necunoscut"), varsta(0), medie(0.0) {
cout << " [constructor implicit]" << endl;
}
// constructor cu parametri, folosind lista de initializare
Student(string n, int v, double m) : nume(n), varsta(v), medie(m) {
cout << " [constructor pentru " << nume << "]" << endl;
}
// constructor de copiere
Student(const Student &alt)
: nume(alt.nume), varsta(alt.varsta), medie(alt.medie) {
cout << " [copiere pentru " << nume << "]" << endl;
}
~Student() {
cout << " [destructor pentru " << nume << "]" << endl;
}
// functii de acces, cu validare
bool setMedie(double m) {
if (m < 1.0 || m > 10.0) return false;
medie = m;
return true;
}
string getNume() const { return nume; }
double getMedie() const { return medie; }
bool promovat() const { return medie >= 5.0; }
void afiseaza() const {
cout << left << setw(18) << nume
<< right << setw(4) << varsta << " ani"
<< setw(8) << fixed << setprecision(2) << medie
<< " " << (promovat() ? "promovat" : "restanta") << endl;
}
};
int main()
{
cout << "Creare obiecte:" << endl;
Student s1("Popescu Ion", 20, 9.15);
Student s2("Ionescu Maria", 21, 4.30);
Student s3 = s1; // apeleaza constructorul de copiere
cout << "\nLista:" << endl;
s1.afiseaza();
s2.afiseaza();
s3.afiseaza();
cout << "\nIncercare de setare a mediei la 15: ";
cout << (s2.setMedie(15.0) ? "acceptat" : "RESPINS de validare") << endl;
cout << "\nDistrugere (ordine inversa):" << endl;
return 0;
}
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
// scriere
{
ofstream fout("date_cpp.txt");
if (!fout) { cerr << "Nu pot scrie!" << endl; return 1; }
fout << "Popescu Ion 20 9.15" << endl;
fout << "Ionescu Maria 21 8.70" << endl;
} // fisierul se inchide AUTOMAT aici, prin destructor
// citire
ifstream fin("date_cpp.txt");
if (!fin) { cerr << "Nu pot citi!" << endl; return 1; }
string nume, prenume;
int varsta;
double medie;
cout << "Continutul fisierului:" << endl;
while (fin >> nume >> prenume >> varsta >> medie) {
cout << " " << nume << " " << prenume
<< ", " << varsta << " ani, media " << medie << endl;
}
fin.close();
// citire linie cu linie
ifstream f2("date_cpp.txt");
string linie;
int nr = 0;
cout << "\nLinie cu linie:" << endl;
while (getline(f2, linie)) {
cout << " " << ++nr << ": " << linie << endl;
}
return 0;
}
10Atelier de cod
Casetele acceptă și C++: cout, string, clase cu constructori și destructori. Urmăriți în ieșire momentul exact în care se apelează fiecare.
b este distrus la acolada care închide blocul interior, nu la sfârșitul lui main. Durata de viață a unui obiect este legată de domeniul în care a fost declarat.11Sarcini de lucru
- Afișați un tabel aliniat folosind
setw,left,rightșisetfill. - Verificați experimental că
setwacționează doar asupra următoarei valori afișate. - Definiți o clasă
Punctcu coordonate private și metode pentru distanța până la origine. - Adăugați clasei un constructor implicit, unul cu parametri și un destructor care afișează mesaje.
- Urmăriți în consolă ordinea apelurilor pentru mai multe obiecte, inclusiv într-un bloc interior.
- Implementați validarea datelor în funcțiile de tip
setși testați valori nepermise. - Scrieți și citiți date dintr-un fișier folosind
ofstreamșiifstream. - Comparați varianta C++ cu cea în C a aceluiași program și notați diferențele de lizibilitate.
12Aplicație de aprofundare
Vector care gestionează un tablou
alocat dinamic: constructor cu dimensiune, constructor de copiere, destructor care eliberează memoria,
metode de adăugare cu redimensionare automată, acces cu verificarea limitelor și supraîncărcarea
operatorului << pentru afișare directă cu cout. Adăugați salvarea și
încărcarea din fișier. Verificați cu mesaje în constructor și destructor că nu apar pierderi de memorie.