public, private, protected în C++

Specificatorii de acces: stabilesc cine poate folosi membrii unei clase și cum se moștenește o clasă de bază.

Sintaxă
class A {
public:      // accesibil de oriunde
protected:   // accesibil în clasă și în clasele derivate
private:     // accesibil doar în clasă (și prietenilor)
};
class B : public A { };

Ce face public, private, protected

public: membrul poate fi folosit de oriunde. private: doar de metodele clasei (și de prietenii ei, declarați cu friend). protected: de metodele clasei și de cele ale claselor derivate din ea. Un specificator se aplică tuturor membrilor de după el, până la următorul.

Regula de bază a încapsulării: datele sunt private, iar interfața (metodele pe care le folosesc alții) este public. Astfel poți schimba modul intern de păstrare a datelor fără să strici codul care folosește clasa.

Aceleași cuvinte apar la moștenire: class Student : public Persoana păstrează accesul membrilor moșteniți (forma folosită aproape mereu). Cu moștenire protected sau private, membrii publici ai bazei devin protejați, respectiv privați, în clasa derivată. Implicit, class moștenește private, iar struct moștenește public.

Exemple

Exemplul 1: Cele trei niveluri de acces

Angajat poate folosi salariu_baza_ (protejat) din Persoana, dar nu cnp_ (privat). Din main se pot folosi doar membrii publici.

#include <print>
#include <string>
#include <utility>

class Persoana {
public:
    Persoana(std::string nume, std::string cnp) : nume(std::move(nume)), cnp_(std::move(cnp)) {}
    std::string nume;                         // public
    bool cnp_valid() const { return cnp_.size() == 13; }
protected:
    double salariu_baza_ = 4050;               // vizibil în clasele derivate
private:
    std::string cnp_;                          // doar în Persoana
};

class Angajat : public Persoana {
public:
    using Persoana::Persoana;
    double salariu_cu_bonus() const { return salariu_baza_ * 1.1; }
};

int main() {
    Angajat a("Mihai", "1900101223344");
    std::println("{}: CNP valid = {}", a.nume, a.cnp_valid());
    std::println("Salariu cu bonus: {:.2f} lei", a.salariu_cu_bonus());
}

Rezultat

Mihai: CNP valid = true
Salariu cu bonus: 4455.00 lei

Exemplul 2: Diferența dintre class și struct

#include <print>

struct S { int x = 1; };    // x este public
class C {
    int x = 2;              // x este privat
public:
    int valoare() const { return x; }
};

int main() {
    S s;
    C c;
    std::println("S::x = {}", s.x);
    std::println("C::x prin metodă = {}", c.valoare());
    // c.x nu s-ar compila: x este privat
}

Rezultat

S::x = 1
C::x prin metodă = 2

Greșeli frecvente

  • Faci toate datele public „ca să fie mai simplu”. Oricine le poate modifica fără verificări (de exemplu un sold negativ); folosește metode publice care verifică valorile.
  • Scrii class Student : Persoana fără public. La class moștenirea implicită este privată, deci nu mai poți apela din afară metodele publice ale lui Persoana printr-un Student.

Comenzi înrudite

  • class: Definește un tip nou care grupează date (membri) și funcțiile care lucrează cu ele (metode); baza programării orientate pe obiecte.
  • struct: Grupează mai multe valori într-un singur tip; ca o clasă, dar cu membri publici implicit.
  • friend: Dă unei funcții sau altei clase acces la membrii privați și protejați ai clasei.
  • virtual: Marchează o metodă care poate fi suprascrisă în clasele derivate; apelul printr-un pointer sau o referință la bază alege varianta tipului real.