Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекции / Лекция 3-4n.docx
Скачиваний:
0
Добавлен:
11.02.2026
Размер:
74.69 Кб
Скачать

Вложенные пользовательские типы данных в классах

В отличие от функций, которые не могут быть вложены (находится внутри друг друга), в языке C++ пользовательские типы данных могут быть определены (вложены) внутри класса. Для этого нужно просто определить пользовательский тип внутри класса под соответствующим спецификатором доступа.

Вот вышеприведенная программа, но уже с FruitList, определенным внутри класса:

#include <iostream>

class Fruit {

public:

// Мы переместили FruitList внутрь класса под спецификатором //доступа public

enum FruitList {

AVOCADO,

BLACKBERRY,

LEMON

};

private:

FruitList m_type;

public:

Fruit (FruitList type): m_type(type) {}

FruitList getType () {return m_type;}

};

Int main () {

// Доступ к FruitList осуществляется через Fruit

Fruit avocado (Fruit::AVOCADO);

if (avocado.getType () == Fruit::AVOCADO)

std::cout << "I am an avocado!";

else

std::cout << "I am not an avocado!";

return 0;

}

Обратите внимание:

    Во-первых, FruitList теперь определен внутри тела класса.

    Во-вторых, мы определили его под спецификатором доступа public, т.е. сделали доступ к FruitList открытым.

По сути, классы работают как пространства имен для любых вложенных типов.

В первом примере мы имеем доступ к перечислителю AVOCADO напрямую, так как AVOCADO определен в глобальной области видимости (мы могли бы предотвратить это, используя класс enum вместо обычного enum, и тогда доступ к AVOCADO осуществлялся бы через FruitList::AVOCADO).

Теперь, поскольку FruitList считается частью класса, доступ к перечислителю AVOCADO осуществляется через имя класса, например: Fruit::AVOCADO.

Обратите внимание, поскольку классы enum также работают как пространства имен, и если бы мы поместили класс enum (вместо обычного enum) с именем FruitList внутрь класса Fruit, то доступ к перечислителю AVOCADO осуществлялся бы через Fruit::FruitList::AVOCADO.

Другие вложенные пользовательские типы данных в классах

Хотя перечисления являются наиболее распространенным вложенным пользовательским типом данных внутри классов, язык C++ также позволяет определять и другие пользовательские типы внутри классов, такие как псевдонимы типов (typedef и type alias) и даже другие классы!

=====================

в C++11 ввели улучшенный синтаксис для typedef, который имитирует способ объявления переменных.

Этот синтаксис называется type alias.

С помощью type alias мы пишем имя, которое затем используется как синоним конкретного типа данных (т.е. принцип тот же, но синтаксис более удобен).

Следующий typedef:

typedef double time_t; // используем time_t в качестве псевдонима //для типа double

В С++11 можно объявить, как:

using time_t = double; // используем time_t в качестве //псевдонима для типа double

Эти два способа функционально эквивалентны.

Обратите внимание, что хоть мы и используем ключевое слово using, оно не имеет ничего общего с using-директивами. Это ключевое слово имеет различный функционал в зависимости от контекста.

Новый синтаксис создания псевдонимов создает меньше проблем при использовании в сложных ситуациях, и его рекомендуется применять вместо обычного typedef.

Правило: Используйте type alias вместо typedef.

=============================

Как и любой обычный член класса, вложенный класс будет иметь доступ ко всем членам класса-оболочки (в котором он размещен). Однако вложенные классы не имеют доступа к указателю this класса-оболочки.

Определение вложенных типов не очень распространено, но Стандартная библиотека C++ все же использует это в некоторых случаях.