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

Clase imbricate

O clasă imbricată (nested class) este o clasă al cărei corp este definit în interiorul altei clase. De obicei, clasele imbricate sunt folosite pentru a descrie entități care există doar în cadrul unui obiect al clasei exterioare, în special atunci când clasa exterioară lucrează cu un set de obiecte ale clasei imbricate.

Să analizăm un exemplu simplu. Presupunem că trebuie să definim pentru un utilizator date care descriu contul său (login, parolă):

#include <iostream>
 
class Person
{
private:
    std::string name;
 
    class Account   // clasă imbricată
    {
    public:
        Account(const std::string& p_email, const std::string& p_password)
        {
            email = p_email;
            password = p_password;
        }
        std::string email;
        std::string password;
    };
    Account account{"", ""};    // variabilă de tipul clasei imbricate Account
public:
    Person(const std::string& p_name, const std::string& p_email, const std::string& p_password)
    {
        name = p_name;
        account = Account(p_email, p_password);
    }
    void print()
    {
        std::cout<<"Name: " << name << "\n" << "Email: " << account.email << "\n"
        << "Password: " << account.password << std::endl; 
    }
};
 
int main()
{
    Person tom{"Tom", "tom@localhost.com", "qwerty"};
    tom.print();
}

Aici, clasa Person reprezintă o clasă de utilizator. Iar datele contului său sunt extrase într-o clasă separată — Account. Clasa Account este definită ca private. Astfel, putem accesa această clasă doar din interiorul clasei Person.

class Account   // clasă imbricată
{
public:
    Account(std::string p_email, std::string p_password)
    {
        email = p_email;
        password = p_password;
    }
    std::string email;
    std::string password;
};

În clasele imbricate se pot folosi și specificatori de acces. În acest caz, câmpurile email și password și constructorul sunt declarate publice, pentru a putea fi accesate în clasa Person, în afara clasei Account. Oricum, din moment ce Account este private, aceste câmpuri sunt inaccesibile din afara clasei Person.

Pentru a stoca datele contului unui obiect concret Person, este definită variabila account:

Account account{"", ""};    // variabilă de tipul clasei imbricate Account

Aceasta este inițializată cu date goale — șiruri goale pentru email și parolă.

În constructorul clasei Person primim datele pentru email și parolă și pe baza acestora creăm un obiect Account:

account = Account(p_email, p_password);

Deoarece câmpurile email și password sunt publice, putem accesa aceste date în funcțiile clasei Person, de exemplu, le afișăm în funcția print:

void print()
{
    std::cout<<"Name: " << name << "\n" << "Email: " << account.email << "\n"
    << "Password: " << account.password << std::endl; 
}

În funcția main creăm un obiect Person și transmitem datele, inclusiv pentru obiectul Account:

Person tom{"Tom", "tom@localhost.com", "qwerty"};
tom.print();

Ieșirea în consolă:

Name: Tom
Email: tom@localhost.com
Password: qwerty

În exemplul de mai sus, obiectele Account nu pot fi create sau utilizate în afara clasei Person, deoarece Account este privată. Totuși, o putem face publică și apoi o putem accesa din afara clasei Person:

#include <iostream>
 
class Person
{
public:
    class Account   // clasă imbricată
    {
    public:
        Account(const std::string& p_email, const std::string& p_password)
        {
            email = p_email;
            password = p_password;
        }
        std::string email{};
        std::string password{};
    };
    Person(const std::string& p_name, const Account& p_account)
    {
        name = p_name;
        account = p_account;
    }
    void print()
    {
        std::cout<<"Name: " << name << "\n" << "Email: " << account.email << "\n"
        << "Password: " << account.password << std::endl;
         
    }
private:
    std::string name;
    Account account{"", ""};    // variabilă de tipul clasei imbricate Account
};
 
int main()
{
    Person::Account account{"bob@somemail.com", "qwerty"};
    Person bob{"Bob", account};
    bob.print();
}

Acum clasa imbricată este publică. Putem chiar să creăm obiecte de acest tip și să accesăm membrii săi folosind numele clasei externe:

Person::Account account{"bob@somemail.com", "qwerty"};

Funcțiile unei clase imbricate pot face referire directă la membrii statici ai clasei externe, precum și la orice alte tipuri definite în clasa exterioară. Accesul la alți membri ai clasei exterioare se poate realiza din clasa imbricată prin metode standard: printr-un obiect al clasei, pointer sau referință la obiectul clasei. De asemenea, funcțiile clasei imbricate pot accesa inclusiv membri private și constante definite în clasa exterioară.