Ce face friend
Membrii private sunt accesibili doar metodelor clasei. Uneori o funcție din afara clasei are nevoie de ei: cel mai des operatorul de afișare operator<<, care trebuie să fie funcție liberă (în stânga are fluxul, nu obiectul). Declarând-o friend în clasă, îi dai acces.
Prietenia este dată de clasă, nu cerută: doar clasa poate spune cine îi este prieten. Nu se moștenește și nu este reciprocă (dacă A este prietena lui B, B nu devine automat prietena lui A).
O funcție prietenă poate fi definită chiar în interiorul clasei; atunci este găsită doar prin argumentele de tipul clasei (un stil recomandat pentru operatori).
Exemple
Exemplul 1: Operator de afișare prieten
#include <iostream>
#include <string>
#include <utility>
class Produs {
public:
Produs(std::string nume, double pret) : nume_(std::move(nume)), pret_(pret) {}
friend std::ostream& operator<<(std::ostream& out, const Produs& p) {
return out << p.nume_ << " (" << p.pret_ << " lei)";
}
private:
std::string nume_;
double pret_;
};
int main() {
Produs p("Caiet", 8.5);
std::cout << "Am cumpărat: " << p << '\n';
}
Rezultat
Am cumpărat: Caiet (8.5 lei)
Exemplul 2: Clasă prietenă
Auditor poate citi soldul privat al oricărui Cont, fără ca soldul să devină public pentru restul programului.
#include <print>
class Cont {
public:
explicit Cont(double sold) : sold_(sold) {}
private:
double sold_;
friend class Auditor;
};
class Auditor {
public:
static bool verifica(const Cont& c) { return c.sold_ >= 0; }
};
int main() {
Cont bun(150), rau(-20);
std::println("Cont 1 corect: {}", Auditor::verifica(bun));
std::println("Cont 2 corect: {}", Auditor::verifica(rau));
}
Rezultat
Cont 1 corect: true
Cont 2 corect: false
Greșeli frecvente
- Folosești
friendca să ocolești încapsularea peste tot. Dacă multe funcții externe au nevoie de membrii privați, probabil că acele funcții ar trebui să fie metode sau că interfața publică e incompletă. - Te aștepți ca o clasă derivată din
Auditorsă fie și ea prietenă cuCont. Prietenia nu se moștenește.
Comenzi înrudite
operator: Definește ce face un operator (+, ==, <<, [], () etc.) pentru tipurile tale, ca obiectele să se folosească la fel de natural ca numerele.class: Definește un tip nou care grupează date (membri) și funcțiile care lucrează cu ele (metode); baza programării orientate pe obiecte.public, private, protected: Specificatorii de acces: stabilesc cine poate folosi membrii unei clase și cum se moștenește o clasă de bază.