Вложенные классы

Последнее обновление: 11.03.2023

Вложенный класс (nested class) — это класс, определение которого находится внутри другого класса. Обычно вложенные классы применяются для описания таких сущностей, которые могут существовать только в рамках объекта внешнего класса, особенно когда внешний класс работает с набором объектов вложенного класса.

Рассмотрим небольшой пример. Допустим, нам надо определить для пользователя данные, которые описывают его учетную запись (логин, пароль):

#include <iostream>

class Person
{
private:
	std::string name;

    class Account   // вложенный класс
    {
    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{"", ""};    // переменная вложенного класса 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();
}

Здесь класс Person представляет класс пользователя. А данные его учетной записи выделены в отдельный класс - Account. Класс Account определен как приватный. Таким образом, обращаться к этому классу мы сможем только внутри класса Person.

class Account   // вложенный класс
{
public:
    Account(std::string p_email, std::string p_password)
    {
        email = p_email;
        password = p_password;
    }
    std::string email;
    std::string password;
};

Во вложенных классах также можно использовать специафикаторы доступа. В данном случае поля email и password и конструктор определены как публичные, общедоступные, чтобы их можно было использовать в классе Person вне класса Account. Тем более, что так как класс Account - приватный, эти поля все равно недоступны из вне класса Person.

Для хранения данных аккаунта конкретного объекта Person определена переменная account:

Account account{"", ""};    // переменная вложенного класса Account

В данном случае она инициализируется начальными данными - пустыми строками для email и пароля.

В конструкторе класса Person получаем данные для email и пароля и на их основе создаем объект Account:

account = Account(p_email, p_password);

Поскольку поля email и password - публичные, мы можем обратиться в функциях класса Person, например, выведем в функции print их значения:

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

В функции main создаем один объект Person и передаем через конструктор данные в том числе для объекта Account:

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

Консольный вывод программы:

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

В примере выше объекты Account нельзя создавать или использовать вне класса Person, так как класс Account является приватным. Однако мы можем также сделать его общедоступным и после этого обращаться к нему вне класса Person:

#include <iostream>

class Person
{
public:
    class Account   // вложенный класс
    {
    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{"", ""};    // переменная вложенного класса Account
};

int main()
{
    Person::Account account{"bob@somemail.com", "qwerty"};
    Person bob{"Bob", account};
    bob.print();
}

Теперь вложенный класс является публичным. Мы можем даже создать объекты этого класса и обращаться к его переменным и функциям, используя имя внешнего класса:

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

Функции вложенного класса могут напрямую ссылаться на статические члены внешнего класса, а также на любые другие типы, определенные во внешнем классе. Доступ к другим членам внешнего класса можно получить из вложенного класса стандартными способами: через объект класса, указатель или ссылку на объект класса. При этом функции вложенного класса могут обращаться в том числе к приватным переменным и константам, которые определены во внешнем классе.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850