MySQL Java JavaScript PHP Python HTML-CSS C-sharp C++ Go

Membri statici ai clasei

Pe lângă variabilele și metodele care aparțin direct unui obiect, C++ permite definirea de variabile și metode care aparțin direct clasei, sau altfel spus — membri statici ai clasei. Variabilele și metodele statice aparțin clasei în ansamblu. Pentru definirea lor se folosește cuvântul cheie static.

Câmpuri statice

Variabilele statice sunt utilizate de obicei pentru a stoca valori specifice clasei, comune tuturor obiectelor clasei. Cu alte cuvinte, câmpurile statice stochează starea întregii clase. O variabilă statică este definită o singură dată și va exista chiar dacă nu au fost create obiecte ale clasei.

Un exemplu reprezentativ pentru variabilele statice sunt diverșii contori. De exemplu, trebuie să stocăm numărul de obiecte create. Această valoare ține de clasă, însă nu depinde de un obiect concret. Să vedem un exemplu:

#include <iostream>
 
class Person
{
public:
    Person(std::string p_name, unsigned p_age)
    {
        ++count;    // la crearea unui obiect nou, incrementăm contorul
        name = p_name;
        age = p_age;
    }
    void print_count()
    {
        std::cout << "Created " << count << " objects" << std::endl;
    }
private:
    std::string name;
    unsigned age;
    static inline unsigned count{};  // câmp static – contor pentru obiectele Person
};
 
int main()
{
    Person tom{"Tom", 38};
    Person bob{"Bob", 42};
    Person sam{"Sam", 25};
    tom.print_count();
    bob.print_count();
    sam.print_count();
}

Aici, în clasa Person, este definită variabila statică count cu ajutorul cuvântului cheie static:

static inline unsigned count{}; // inițializăm cu zero

Atenție: după static apare cuvântul inline. Acest cuvânt nu este obligatoriu pentru variabilele statice în general, dar este necesar aici pentru inițializarea variabilei count, în acest caz — cu zero.

La crearea fiecărui obiect nou, în constructor, incrementăm contorul cu 1:

++count;

În funcțiile clasei Person, putem accesa această variabilă statică. De exemplu, în funcția print_count afișăm valoarea ei în consolă.

Pentru test, în funcția main creăm trei obiecte Person, apoi pentru fiecare apelăm funcția print_count. Însă, deoarece count este o variabilă statică și aparține întregii clase, nu unui obiect individual, în toate cele trei cazuri se va afișa numărul 3.

Funcții statice

Funcțiile statice, de asemenea, aparțin clasei în ansamblu și nu depind de un obiect individual. De regulă, funcțiile membre statice sunt folosite pentru a lucra cu variabile statice. De exemplu, în exemplul de mai sus, funcția print_count() afișează valoarea variabilei statice count și nu depinde de un obiect concret, nu folosește și nu modifică variabilele și funcțiile obiectului. Prin urmare, o astfel de funcție poate fi și este mai bine să fie declarată ca statică:

#include <iostream>
 
class Person
{
public:
    Person(std::string p_name, unsigned p_age)
    {
        ++count;
        name = p_name;
        age = p_age;
    }
    // funcție statică
    static void print_count()
    {
        std::cout << "Created " << count << " objects" << std::endl;
    }
private:
    std::string name;
    unsigned age;
    static inline unsigned count{};
};
 
int main()
{
    Person tom{"Tom", 38};
    Person bob{"Bob", 42};
    Person sam{"Sam", 25};
    tom.print_count();  // Created 3 objects
}

Pentru a defini o funcție statică, în fața ei se pune cuvântul cheie static:

static void print_count()

La astfel de funcții putem apela și printr-un obiect:

tom.print_count();

Accesarea membrilor statici ai clasei

După cum s-a demonstrat mai sus, pentru a accesa membrii statici se poate folosi numele unui obiect. Totuși, C++ acceptă și altă sintaxă:

clasa::membru_clasă

După numele clasei urmează operatorul :: și numele membrului static al clasei. De exemplu:

#include <iostream>
 
class Person
{
public:
    static inline unsigned maxAge{120};  // variabilă statică publică
    Person(std::string p_name, unsigned p_age)
    {
        ++count;
        name = p_name;
        if(p_age < maxAge)  // dacă valoarea nu depășește maximul
            age = p_age;
    }
    static void print_count()
    {
        std::cout << "Created " << count << " objects" << std::endl;
    }
private:
    std::string name;
    unsigned age{1};
    static inline unsigned count{};
};
 
int main()
{
    Person tom{"Tom", 38};
    Person bob{"Bob", 42};
    Person sam{"Sam", 25};
     
    // accesăm funcția statică print_count
    Person::print_count();
    // accesăm variabila statică maxAge
    std::cout << "Max age: " << Person::maxAge << std::endl;
    // modificăm variabila statică maxAge
    Person::maxAge = 110;
    std::cout << "Max age: " << Person::maxAge << std::endl;
}

Aici este adăugată o variabilă statică publică maxAge, care reprezintă vârsta maximă. Deoarece această valoare nu depinde de un obiect anume, ci de clasa Person în ansamblu (valabil pentru toți oamenii), definim această variabilă ca statică. În constructor, folosim această variabilă pentru a valida vârsta transmisă. Dacă vârsta este mai mare decât maximul, atunci vârsta este setată la valoarea implicită – 1.

În funcția main putem accesa funcția statică print_count și variabila maxAge folosind numele clasei:

Person::print_count();
Person::maxAge

Ieșirea în consolă a programului:

Created 3 objects  
Max age: 120  
Max age: 110

Constante statice

De asemenea, putem defini constante statice. De exemplu, în cazul anterior este puțin probabil ca valoarea lui maxAge să se schimbe. Prin urmare, putem defini această variabilă ca o constantă. Valoarea ei nu va putea fi modificată, iar în rest funcționează ca o variabilă statică:

#include <iostream>
 
class Person
{
public:
    static inline const unsigned maxAge{120};  // constantă statică
    Person(std::string p_name, unsigned p_age)
    {
        ++count;
        name = p_name;
        if(p_age < maxAge)
            age = p_age;
    }
    static void print_count()
    {
        std::cout << "Created " << count << " objects" << std::endl;
    }
private:
    std::string name;
    unsigned age{1};
    static inline unsigned count{};
};
 
int main()
{
    Person tom{"Tom", 38};
    Person bob{"Bob", 42};
     
    // accesăm membrii statici ai clasei
    Person::print_count();
    std::cout << "Max age: " << Person::maxAge << std::endl;
}